diff --git a/Gopkg.lock b/Gopkg.lock
index 02553eca6..03895783f 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -2,59 +2,59 @@
 
 
 [[projects]]
-  digest = "1:ecf78eacf406c42f07f66d6b79fda24d2b92dc711bfd0760d0c931678f9621fe"
+  digest = "1:69b1cc331fca23d702bd72f860c6a647afd0aa9fcbc1d0659b1365e26546dd70"
   name = "github.com/Sirupsen/logrus"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "ad15b42461921f1fb3529b058c6786c6a45d5162"
-  version = "v1.1.1"
+  pruneopts = "UT"
+  revision = "bcd833dfe83d3cebad139e4a29ed79cb2318bf95"
+  version = "v1.2.0"
 
 [[projects]]
-  digest = "1:aba270497eb2d49f5cba6f4162d524b9a1195a24cbce8be20bf56a0051f47deb"
+  digest = "1:705c40022f5c03bf96ffeb6477858d88565064485a513abcd0f11a0911546cb6"
   name = "github.com/blang/semver"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "2ee87856327ba09384cabd113bc6b5d174e9ec0f"
   version = "v3.5.1"
 
 [[projects]]
   branch = "master"
-  digest = "1:dd9ac3f14c49f44e3921aeafa38653e04ae44e219eebc6e0757c04e19098ca40"
+  digest = "1:210dd3b6f30ebc5ff2e0b4795b5141ee4578c29b38df0326fb140863d45c01fa"
   name = "github.com/creack/goselect"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "58854f77ee8d858ce751b0a9bcc5533fef7bfa9e"
 
 [[projects]]
-  digest = "1:d57500f681aba6bbb064c4b885995fd2e3521a7b9ef05f19feedd3b8e72a020e"
+  digest = "1:ce303e1d83a733bda89c5bad61fcf7e86b9f68b97bf783509192090ddd3919cb"
   name = "github.com/davidmz/go-pageant"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "30ad2d03e9fe97a029a6a6dc87bff319e0bb6bc4"
   version = "v1.0.1"
 
 [[projects]]
   branch = "master"
-  digest = "1:9a8c267811e3b6fae377040b8bf050fcee59fdb8cade14ad3f929d924e08093d"
+  digest = "1:c3c09c0f941175181747b2d6948fd1add3ba82e66215aae78ec9b44d97d8ed40"
   name = "github.com/getlantern/context"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "624d99b1798d7c5375ea1d3ca4c5b04d58f7c775"
+  pruneopts = "UT"
+  revision = "539649cc311886ee3604204cfab46f72b5f40950"
 
 [[projects]]
   branch = "master"
   digest = "1:56460acc7affba18fa344130886a6f841988d1368a051759d2e0c03ef6255f54"
   name = "github.com/getlantern/errors"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "e24b7f4ff7c70be59bbefca6b7695d68cda8b399"
 
 [[projects]]
   branch = "master"
-  digest = "1:785bb882679010d1fe5b6b456f3e28b16d54e8418e33cd769e3322c49c47a2e8"
+  digest = "1:128515bf48085482f3b1269701a0be1b119087447d8f666a27211bdacf0b5dc9"
   name = "github.com/getlantern/golog"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "cca714f7feb5df8e455f409b549d384441ac4578"
 
 [[projects]]
@@ -62,7 +62,7 @@
   digest = "1:f12c7103ba4c446c6822f331ada3e5f0c3626be111a115e92700cd2724bca9ed"
   name = "github.com/getlantern/hex"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "083fba3033ad473db3dd31c9bb368473d37581a7"
 
 [[projects]]
@@ -70,7 +70,7 @@
   digest = "1:916634881c70eb3c2201419786896254d601a786a9124e662a079d4649df160d"
   name = "github.com/getlantern/hidden"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "d52a649ab33af200943bb599898dbdcfdbc94cb7"
 
 [[projects]]
@@ -78,27 +78,26 @@
   digest = "1:f84e2692edf40301ae0ce718695cde032f5c6964e4fad812749eb1eaefa95785"
   name = "github.com/getlantern/ops"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "37353306c90844c8e0591956f56611f46299d202"
 
 [[projects]]
-  branch = "master"
-  digest = "1:0060263f361770203e8bc253fc45ed71a7ba092f7fe632f2148e9e95453ea32b"
+  digest = "1:bd5504d3204cc1625bc017e477690ad7da71f5c800dc5efdf8a9a7d4feebe2e7"
   name = "github.com/getlantern/systray"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "e31397f8c6928d98a8a9a7e80087aebcf0090beb"
+  pruneopts = "UT"
+  revision = "89b3d9c45cc69f861868cc7f3159eba2b4cdfb22"
 
 [[projects]]
   branch = "master"
-  digest = "1:23edf5aaca7a1f15d68215ac41595c0732152757e9d7b3f282821222784049f1"
+  digest = "1:36fe9527deed01d2a317617e59304eb2c4ce9f8a24115bcc5c2e37b3aee5bae4"
   name = "github.com/gin-contrib/sse"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "22d885f9ecc78bf4ee5d72b937e4bbcdc58e8cae"
 
 [[projects]]
-  digest = "1:7f029513a3c64c1fc923af79bf27d4fd0ce4fafdd13b421c1884d52c84e9c600"
+  digest = "1:d5083934eb25e45d17f72ffa86cae3814f4a9d6c073c4f16b64147169b245606"
   name = "github.com/gin-gonic/gin"
   packages = [
     ".",
@@ -106,48 +105,47 @@
     "json",
     "render",
   ]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "b869fe1415e4b9eb52f247441830d502aece2d4d"
   version = "v1.3.0"
 
 [[projects]]
-  digest = "1:c204ec81f754234f2c3c4093cc8cc42151aadedd1129b32539a472fd7881e689"
+  digest = "1:15e27372d379b45b18ac917b9dafc45c45485239490ece18cca97a12f9591146"
   name = "github.com/go-ini/ini"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "9c8236e659b76e87bf02044d06fde8683008ff3e"
   version = "v1.39.0"
 
 [[projects]]
-  digest = "1:cb4e216bd9f58866f42dc65893455b24f879b026fdaa1ecc3aafff625fdb5a66"
+  digest = "1:64a5a67c69b70c2420e607a8545d674a23778ed9c3e80607bfd17b77c6c87f6a"
   name = "github.com/go-ole/go-ole"
   packages = [
     ".",
     "oleutil",
   ]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506"
   version = "v1.2.1"
 
 [[projects]]
-  digest = "1:91358b3a314c1ddfd4d6445ca9c1fb846842c31c153e626730594b3c95f73f4a"
+  digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d"
   name = "github.com/go-stack/stack"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a"
   version = "v1.8.0"
 
 [[projects]]
-  digest = "1:97df918963298c287643883209a2c3f642e6593379f97ab400c2a2e219ab647d"
+  digest = "1:6ba96a683441984156b05568b9d31dbc846d3336d21ac220fcc819a367dc1f65"
   name = "github.com/golang/protobuf"
   packages = ["proto"]
-  pruneopts = "NUT"
-  revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
-  version = "v1.2.0"
+  pruneopts = "UT"
+  revision = "5a0f697c9ed9d68fef0116532c6e05cfeae00e55"
 
 [[projects]]
   branch = "master"
-  digest = "1:46223f4c05549a4f57fe78cbe3348d905f0d91ae7ab8fa4ac1751281dfa52aac"
+  digest = "1:324591cd9122f94cc39a87bd44ec71153672c239e2cff5743bfad96b60be3749"
   name = "github.com/googollee/go-engine.io"
   packages = [
     ".",
@@ -157,159 +155,142 @@
     "transport",
     "websocket",
   ]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "e2f255711dcb2ea41e42c6d9d98c172d7edf6509"
 
 [[projects]]
   branch = "master"
-  digest = "1:5e9a122f51197a970db03a82944e9344201e68f0abd6d66016911cb9ed735572"
+  digest = "1:3eb026ba34d6dd12b45bb6abd63b4e917ebca8d8f3022a139c0881d900ad1bee"
   name = "github.com/googollee/go-socket.io"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "25e1f67559cf5d0e41efbc3e0157bb952596ffc3"
+  pruneopts = "UT"
+  revision = "c8aeb1ed9b49d7de8fef8662efb18f1d289c5f2e"
 
 [[projects]]
-  digest = "1:4a0c072e44da763409da72d41492373a034baf2e6d849c76d239b4abdfbb6c49"
+  digest = "1:7b5c6e2eeaa9ae5907c391a91c132abfd5c9e8a784a341b5625e750c67e6825d"
   name = "github.com/gorilla/websocket"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d"
   version = "v1.4.0"
 
 [[projects]]
-  digest = "1:06d89db601972cb01beee33ea815839d29ba8048c4b0d71a79a3e6af96063acf"
+  digest = "1:a3986520f4fa5d398a1407186b1d53e3d56825033dc70c681bd05ca6f47e7c4b"
   name = "github.com/itsjamie/gin-cors"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "97b4a9da79331dfa2b6d35f4cdd1e50f5148859c"
   version = "1.0.0"
 
 [[projects]]
-  digest = "1:8e36686e8b139f8fe240c1d5cf3a145bc675c22ff8e707857cdd3ae17b00d728"
+  digest = "1:be97e109f627d3ba8edfef50c9c74f0d0c17cbe3a2e924a8985e4804a894f282"
   name = "github.com/json-iterator/go"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "1624edc4454b8682399def8740d46db5e4362ba4"
-  version = "v1.1.5"
+  pruneopts = "UT"
+  revision = "36b14963da70d11297d313183d7e6388c8510e1e"
+  version = "1.0.0"
 
 [[projects]]
   branch = "master"
-  digest = "1:263f9b0a0bcbfff9d5e7d9f2aa11f53995d98214fe0fb97e429e7a5f4534a0f9"
+  digest = "1:caf6db28595425c0e0f2301a00257d11712f65c1878e12cffc42f6b9a9cf3f23"
   name = "github.com/kardianos/osext"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "ae77be60afb1dcacde03767a8c37337fad28ac14"
 
 [[projects]]
-  digest = "1:4059c14e87a2de3a434430340521b5feece186c1469eff0834c29a63870de3ed"
+  digest = "1:0a69a1c0db3591fcefb47f115b224592c8dfa4368b7ba9fae509d5e16cdc95c8"
   name = "github.com/konsorten/go-windows-terminal-sequences"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242"
   version = "v1.0.1"
 
 [[projects]]
-  digest = "1:48306f3ac75da2e9facec89df74e5ac14737402af373171bc4b91655e7d7d097"
+  digest = "1:7ad278b575635babef38e4ad4219500c299a58ea14b30eb21383d0efca00b369"
   name = "github.com/kr/binarydist"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "88f551ae580780cc79d12ab4c218ba1ca346b83a"
   version = "v0.1.0"
 
 [[projects]]
-  digest = "1:47fa0ef6ae6b0387dacb77c7ab8827b4ef621650fd613e43ece61de4cb3f5019"
+  digest = "1:9cedee824c21326bd26950bd9e1ffe9dc4e7ca03dc8634d0e6f954ee6a383172"
   name = "github.com/kr/fs"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "1455def202f6e05b95cc7bfc7e8ae67ae5141eba"
   version = "v0.1.0"
 
 [[projects]]
-  digest = "1:bffa444ca07c69c599ae5876bc18b25bfd5fa85b297ca10a25594d284a7e9c5d"
+  digest = "1:fa610f9fe6a93f4a75e64c83673dfff9bf1a34bbb21e6102021b6bc7850834a3"
   name = "github.com/mattn/go-isatty"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
-  version = "v0.0.4"
+  pruneopts = "UT"
+  revision = "57fdcb988a5c543893cc61bce354a6e24ab70022"
 
 [[projects]]
-  digest = "1:d0164259ed17929689df11205194d80288e8ae25351778f7a3421a24774c36f8"
+  digest = "1:7efe48dea4db6b35dcc15e15394b627247e5b3fb814242de986b746ba8e0abf0"
   name = "github.com/mattn/go-shellwords"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "02e3cf038dcea8290e44424da473dd12be796a8a"
   version = "v1.0.3"
 
 [[projects]]
-  digest = "1:a4b80152551d55dbb835dd81ffa33157f0224b313ae94640c64c9ae5403098db"
+  digest = "1:b20d8767957e40b9302a8caaee88caa698513fbd972509a54555302c3aebfa04"
   name = "github.com/miekg/dns"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "915ca3d5ffd945235828a097c917311a9d86ebb4"
-  version = "v1.0.14"
+  pruneopts = "UT"
+  revision = "7064f7248f5fa5fd79382a76328b4e200b79e4ae"
+  version = "v1.0.15"
 
 [[projects]]
-  branch = "master"
-  digest = "1:a4df73029d2c42fabcb6b41e327d2f87e685284ec03edf76921c267d9cfc9c23"
+  digest = "1:78bbb1ba5b7c3f2ed0ea1eab57bdd3859aec7e177811563edc41198a760b06af"
   name = "github.com/mitchellh/go-homedir"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4"
-
-[[projects]]
-  digest = "1:2f42fa12d6911c7b7659738758631bec870b7e9b4c6be5444f963cdcfccc191f"
-  name = "github.com/modern-go/concurrent"
-  packages = ["."]
-  pruneopts = "NUT"
-  revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
-  version = "1.0.3"
-
-[[projects]]
-  digest = "1:c6aca19413b13dc59c220ad7430329e2ec454cc310bc6d8de2c7e2b93c18a0f6"
-  name = "github.com/modern-go/reflect2"
-  packages = ["."]
-  pruneopts = "NUT"
-  revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
-  version = "1.0.1"
+  version = "v1.0.0"
 
 [[projects]]
   branch = "master"
-  digest = "1:8b8b71239fc5851930ed3d267a2d310f100d2f3d340d55eff74b210730d75125"
+  digest = "1:1a0539f293ad62dd34cce1c5cc11b0aa2c1c322b2352682e22ecf5aecaf4a8bd"
   name = "github.com/oleksandr/bonjour"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "5dcf00d8b228be86307f952f550f2191d956b9e2"
 
 [[projects]]
   branch = "master"
-  digest = "1:8fe179a5468c41a57dd75dcb283c1a81c4ca38a934380ff996437033d7d9509a"
+  digest = "1:df63a8ddf6fd32f2cdf09db1ada151c8a27f5fe2516ee977b72d6a0707e94910"
   name = "github.com/oxtoacart/bpool"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "4e1c5567d7c2dd59fa4c7c83d34c2f3528b025d6"
 
 [[projects]]
-  digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121"
+  digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
   name = "github.com/pkg/errors"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
   version = "v0.8.0"
 
 [[projects]]
-  digest = "1:3d8d113726023d6c1dd1f29a19f13266d33a0746fe6f14df8da17eb7409a9aa2"
+  digest = "1:98c46dbde8c257608669d6827aacb8c8722d6ea7b4ffd7c4d1ea32ead21bfea9"
   name = "github.com/pkg/sftp"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "08de04f133f27844173471167014e1a753655ac8"
   version = "v1.8.3"
 
 [[projects]]
   branch = "master"
-  digest = "1:ba0f377f1482789a3d8a398ee01f642bd2d6ec97bec11268ccde92677ed1fb5c"
+  digest = "1:e244ec9ef8a91f5d0f640c4d14db6d65938182bb976c07f01f0f6e8f4605c4e9"
   name = "github.com/sfreiberg/simplessh"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "495cbb862a9c6348e0fff479ed1e7b70c871b372"
 
 [[projects]]
@@ -317,40 +298,39 @@
   digest = "1:39853e1ae46a02816e2419e1f590e00682b1a6b60bb988597cf2efb84314da45"
   name = "github.com/skratchdot/open-golang"
   packages = ["open"]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "75fb7ed4208cf72d323d7d02fd1a5964a7a9073c"
 
 [[projects]]
-  digest = "1:919fc2a81add8ac4a7a236dceaf3e4c29ba4df96d13c3f2ce13a4d0132ebefb8"
+  digest = "1:c268acaa4a4d94a467980e5e91452eb61c460145765293dc0aed48e5e9919cc6"
   name = "github.com/ugorji/go"
   packages = ["codec"]
-  pruneopts = "NUT"
-  revision = "b4c50a2b199d93b13dc15e78929cfb23bfdf21ab"
-  version = "v1.1.1"
+  pruneopts = "UT"
+  revision = "c88ee250d0221a57af388746f5cf03768c21d6e2"
 
 [[projects]]
   branch = "master"
-  digest = "1:c205236572ddcd0988a24c06be96a179982e870d2b7d746c95e06d9803cd9462"
+  digest = "1:85ceb7046447e3f5cf21c621ec137b23eb8d02ae9b585dd5c22d65543a0f3020"
   name = "github.com/xrash/smetrics"
   packages = ["."]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "a3153f7040e90324c58c6287535e26a0ac5c1cc1"
 
 [[projects]]
   branch = "master"
-  digest = "1:572a6fb10b136109bd380f283682a2eb05551f3e193ff95a3d4d08d7060fa441"
+  digest = "1:49b892f63d6b54df49cc35901eba38acc3c5309f919b40b3d1e2ff859c8108ba"
   name = "go.bug.st/serial.v1"
   packages = [
     ".",
     "enumerator",
     "unixutils",
   ]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "5f7892a7bb453066bdc6683b9b5d24d9dee03ec1"
 
 [[projects]]
   branch = "master"
-  digest = "1:a0704c8502c6004cbc247cb339c66270cf5f6cfbb032b25237faf93875abeefa"
+  digest = "1:04c834d4d75b1e3c678ffadb336e4c5f8b58786cb7bd1f3ee19a166d76aa9b56"
   name = "golang.org/x/crypto"
   packages = [
     "cast5",
@@ -370,12 +350,12 @@
     "ssh/agent",
     "ssh/terminal",
   ]
-  pruneopts = "NUT"
-  revision = "4d3f4d9ffa16a13f451c3b2999e9c49e9750bf06"
+  pruneopts = "UT"
+  revision = "3d3f9f413869b949e48070b5bc593aa22cc2b8f2"
 
 [[projects]]
   branch = "master"
-  digest = "1:40a3cfcb660b2f6354f669eb8cbea46b5a308b42f349782147301ab66fb57184"
+  digest = "1:223e261c2e2506efad9737b5df18738e3dd0ad05b6d446ec8bcfa3576845183d"
   name = "golang.org/x/net"
   packages = [
     "bpf",
@@ -384,46 +364,45 @@
     "ipv4",
     "ipv6",
   ]
-  pruneopts = "NUT"
-  revision = "c44066c5c816ec500d459a2a324a753f78531ae0"
+  pruneopts = "UT"
+  revision = "adae6a3d119ae4890b46832a2e88a95adc62b8e7"
 
 [[projects]]
   branch = "master"
-  digest = "1:3bcf6eb3757db3e22c41d212f886b86d0f940f86e1af85b13cd31122ac341193"
+  digest = "1:f343f077a5b0bc3a3788b3a04e24dd417e3e25b2acb529c413e212d2c42416ef"
   name = "golang.org/x/sys"
   packages = [
     "unix",
     "windows",
   ]
-  pruneopts = "NUT"
-  revision = "9b800f95dbbc54abff0acf7ee32d88ba4e328c89"
+  pruneopts = "UT"
+  revision = "62eef0e2fa9b2c385f7b2778e763486da6880d37"
 
 [[projects]]
-  digest = "1:0215407129c5f116ae8f6d3af64df59c39d3f606a72ef77a1e6ed874f92a8d9c"
+  digest = "1:1b4724d3c8125f6044925f02b485b74bfec9905cbf579d95aafd1a6c8f8447d3"
   name = "gopkg.in/go-playground/validator.v8"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "5f1438d3fca68893a817e4a66806cea46a9e4ebf"
-  version = "v8.18.2"
+  pruneopts = "UT"
+  revision = "5f57d2222ad794d0dffb07e664ea05e2ee07d60c"
+  version = "v8.18.1"
 
 [[projects]]
   branch = "v0"
-  digest = "1:299a25c4ee90eb917553bb4d51e04b75f1b56bc1b4f5c63ed21e5369fb533855"
+  digest = "1:580aa4af38b87e235950c3a09841bb7f9f329e2495ec5d43c42d7f7fb7f5a464"
   name = "gopkg.in/inconshreveable/go-update.v0"
   packages = [
     ".",
     "download",
   ]
-  pruneopts = "NUT"
+  pruneopts = "UT"
   revision = "d8b0b1d421aa1cbf392c05869f8abbc669bb7066"
 
 [[projects]]
-  digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082"
+  digest = "1:cacb98d52c60c337c2ce95a7af83ba0313a93ce5e73fa9e99a96aff70776b9d3"
   name = "gopkg.in/yaml.v2"
   packages = ["."]
-  pruneopts = "NUT"
-  revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
-  version = "v2.2.1"
+  pruneopts = "UT"
+  revision = "a5b47d31c556af34a302ce5d659e6fea44d90de0"
 
 [solve-meta]
   analyzer-name = "dep"
diff --git a/Gopkg.toml b/Gopkg.toml
index 44e310071..97bc5fa07 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -27,76 +27,28 @@
 
 [[constraint]]
   name = "github.com/Sirupsen/logrus"
-  version = "1.0.6"
+  version = "1.2.0"
 
 [[constraint]]
   name = "github.com/blang/semver"
   version = "3.5.1"
 
 [[constraint]]
-  branch = "master"
-  name = "github.com/creack/goselect"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/getlantern/context"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/getlantern/errors"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/getlantern/filepersist"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/getlantern/golog"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/getlantern/hex"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/getlantern/hidden"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/getlantern/ops"
-
-[[constraint]]
-  name = "github.com/getlantern/stack"
-  version = "1.5.1"
-
-[[constraint]]
-  branch = "master"
+  revision = "89b3d9c45cc69f861868cc7f3159eba2b4cdfb22"
   name = "github.com/getlantern/systray"
 
 [[constraint]]
   name = "github.com/gin-gonic/gin"
-  version = "1.2.0"
+  version = "1.3.0"
 
 [[constraint]]
   name = "github.com/go-ini/ini"
-  version = "1.38.1"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/googollee/go-engine.io"
+  version = "1.39.0"
 
 [[constraint]]
   branch = "master"
   name = "github.com/googollee/go-socket.io"
 
-[[constraint]]
-  name = "github.com/gorilla/websocket"
-  version = "1.2.0"
-
-[[constraint]]
-  branch = "filemode"
-  name = "github.com/inconshreveable/go-update"
-
 [[constraint]]
   name = "github.com/itsjamie/gin-cors"
   version = "1.0.0"
@@ -109,37 +61,13 @@
   name = "github.com/kr/binarydist"
   version = "0.1.0"
 
-[[constraint]]
-  name = "github.com/kr/fs"
-  version = "0.1.0"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/manucorporat/sse"
-
-[[constraint]]
-  name = "github.com/mattn/go-colorable"
-  version = "0.0.9"
-
-[[constraint]]
-  name = "github.com/mattn/go-isatty"
-  version = "0.0.3"
-
-[[constraint]]
-  name = "github.com/mattn/go-ole"
-  version = "1.2.1"
-
 [[constraint]]
   name = "github.com/mattn/go-shellwords"
   version = "1.0.3"
 
 [[constraint]]
-  name = "github.com/miekg/dns"
-  version = "1.0.8"
-
-[[constraint]]
-  branch = "master"
   name = "github.com/mitchellh/go-homedir"
+  version = "1.0.0"
 
 [[constraint]]
   branch = "master"
@@ -149,10 +77,6 @@
   name = "github.com/pkg/errors"
   version = "0.8.0"
 
-[[constraint]]
-  name = "github.com/pkg/sftp"
-  version = "1.8.0"
-
 [[constraint]]
   branch = "master"
   name = "github.com/sfreiberg/simplessh"
@@ -161,18 +85,6 @@
   branch = "master"
   name = "github.com/skratchdot/open-golang"
 
-[[constraint]]
-  name = "github.com/smartystreets/goconvey"
-  version = "1.6.3"
-
-[[constraint]]
-  name = "github.com/stretchr/testify"
-  version = "1.2.2"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/vharitonsky/iniflags"
-
 [[constraint]]
   branch = "master"
   name = "github.com/xrash/smetrics"
@@ -185,27 +97,10 @@
   branch = "master"
   name = "golang.org/x/crypto"
 
-[[constraint]]
-  branch = "master"
-  name = "golang.org/x/net"
-
-[[constraint]]
-  branch = "master"
-  name = "golang.org/x/sys"
-
-[[constraint]]
-  name = "gopkg.in/bluesuncorp/validator.v5"
-  version = "5.12.0"
-
 [[constraint]]
   branch = "v0"
   name = "gopkg.in/inconshreveable/go-update.v0"
 
-[[constraint]]
-  name = "gopkg.in/ini.v1"
-  version = "1.38.1"
-
 [prune]
-  non-go = true
   go-tests = true
-  unused-packages = true
\ No newline at end of file
+  unused-packages = true
diff --git a/main.go b/main.go
index 49add9640..6b0012dfd 100755
--- a/main.go
+++ b/main.go
@@ -335,7 +335,7 @@ var homeTemplate = template.Must(template.New("home").Parse(homeTemplateHtml))
 const homeTemplateHtml = `<!DOCTYPE html>
 <html>
 <head>
-<title>Serial Port Example</title>
+<title>Arduino Create Agent Debug Console</title>
 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
 <script type="text/javascript">
diff --git a/tools/download.go b/tools/download.go
index cd4ec94ec..57ac0419d 100644
--- a/tools/download.go
+++ b/tools/download.go
@@ -10,6 +10,7 @@ import (
 	"encoding/hex"
 	"encoding/json"
 	"errors"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"net/http"
@@ -226,7 +227,7 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
 	// Decompress
 	t.Logger("Unpacking tool " + name)
 
-	location := path.Join(dir(), pack, correctTool.Name, correctTool.Version)
+	location := path.Join( dir(), pack, correctTool.Name, correctTool.Version)
 	err = os.RemoveAll(location)
 
 	if err != nil {
@@ -240,12 +241,12 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
 
 	switch srcType {
 	case "application/zip":
-		location, err = extractZip(body, location)
+		location, err = extractZip(t.Logger, body, location)
 	case "application/x-bz2":
 	case "application/octet-stream":
-		location, err = extractBz2(body, location)
+		location, err = extractBz2(t.Logger, body, location)
 	case "application/x-gzip":
-		location, err = extractTarGz(body, location)
+		location, err = extractTarGz(t.Logger, body, location)
 	default:
 		return errors.New("Unknown extension for file " + correctSystem.URL)
 	}
@@ -376,7 +377,7 @@ func removeStringFromSlice(s []string, r string) []string {
 
 func findBaseDir(dirList []string) string {
 	if len(dirList) == 1 {
-		return filepath.Dir(dirList[0]) + "/"
+		return path.Dir(dirList[0]) + "/"
 	}
 
 	// https://github.com/backdrop-ops/contrib/issues/55#issuecomment-73814500
@@ -385,14 +386,14 @@ func findBaseDir(dirList []string) string {
 		dirList = removeStringFromSlice(dirList, v)
 	}
 
-	commonBaseDir := commonPrefix(os.PathSeparator, dirList)
+	commonBaseDir := commonPrefix('/', dirList)
 	if commonBaseDir != "" {
 		commonBaseDir = commonBaseDir + "/"
 	}
 	return commonBaseDir
 }
 
-func extractZip(body []byte, location string) (string, error) {
+func  extractZip(log func(msg string) , body []byte, location string) (string, error) {
 	path, err := utilities.SaveFileonTempDir("tooldownloaded.zip", bytes.NewReader(body))
 	r, err := zip.OpenReader(path)
 	if err != nil {
@@ -406,9 +407,11 @@ func extractZip(body []byte, location string) (string, error) {
 	}
 
 	basedir := findBaseDir(dirList)
+	log(fmt.Sprintf("selected baseDir %s from Zip Archive Content: %v", basedir, dirList))
 
 	for _, f := range r.File {
 		fullname := filepath.Join(location, strings.Replace(f.Name, basedir, "", -1))
+		log(fmt.Sprintf("generated fullname %s removing %s from %s", fullname, basedir, f.Name))
 		if f.FileInfo().IsDir() {
 			os.MkdirAll(fullname, f.FileInfo().Mode().Perm())
 		} else {
@@ -439,7 +442,7 @@ func extractZip(body []byte, location string) (string, error) {
 	return location, nil
 }
 
-func extractTarGz(body []byte, location string) (string, error) {
+func extractTarGz(log func(msg string),body []byte, location string) (string, error) {
 	bodyCopy := make([]byte, len(body))
 	copy(bodyCopy, body)
 	tarFile, _ := gzip.NewReader(bytes.NewReader(body))
@@ -456,6 +459,7 @@ func extractTarGz(body []byte, location string) (string, error) {
 	}
 
 	basedir := findBaseDir(dirList)
+	log(fmt.Sprintf("selected baseDir %s from TarGz Archive Content: %v", basedir, dirList))
 
 	tarFile, _ = gzip.NewReader(bytes.NewReader(bodyCopy))
 	tarReader = tar.NewReader(tarFile)
@@ -502,36 +506,8 @@ func extractTarGz(body []byte, location string) (string, error) {
 	return location, nil
 }
 
-func (t *Tools) installDrivers(location string) error {
-	OK_PRESSED := 6
-	extension := ".bat"
-	preamble := ""
-	if runtime.GOOS != "windows" {
-		extension = ".sh"
-		// add ./ to force locality
-		preamble = "./"
-	}
-	if _, err := os.Stat(filepath.Join(location, "post_install"+extension)); err == nil {
-		t.Logger("Installing drivers")
-		ok := MessageBox("Installing drivers", "We are about to install some drivers needed to use Arduino/Genuino boards\nDo you want to continue?")
-		if ok == OK_PRESSED {
-			os.Chdir(location)
-			t.Logger(preamble + "post_install" + extension)
-			oscmd := exec.Command(preamble + "post_install" + extension)
-			if runtime.GOOS != "linux" {
-				// spawning a shell could be the only way to let the user type his password
-				TellCommandNotToSpawnShell(oscmd)
-			}
-			err = oscmd.Run()
-			return err
-		} else {
-			return errors.New("Could not install drivers")
-		}
-	}
-	return nil
-}
 
-func extractBz2(body []byte, location string) (string, error) {
+func  extractBz2(log func(msg string),body []byte, location string) (string, error) {
 	bodyCopy := make([]byte, len(body))
 	copy(bodyCopy, body)
 	tarFile := bzip2.NewReader(bytes.NewReader(body))
@@ -548,6 +524,7 @@ func extractBz2(body []byte, location string) (string, error) {
 	}
 
 	basedir := findBaseDir(dirList)
+	log(fmt.Sprintf("selected baseDir %s from Bz2 Archive Content: %v", basedir, dirList))
 
 	tarFile = bzip2.NewReader(bytes.NewReader(bodyCopy))
 	tarReader = tar.NewReader(tarFile)
@@ -596,6 +573,36 @@ func extractBz2(body []byte, location string) (string, error) {
 	return location, nil
 }
 
+
+func (t *Tools) installDrivers(location string) error {
+	OK_PRESSED := 6
+	extension := ".bat"
+	preamble := ""
+	if runtime.GOOS != "windows" {
+		extension = ".sh"
+		// add ./ to force locality
+		preamble = "./"
+	}
+	if _, err := os.Stat(filepath.Join(location, "post_install"+extension)); err == nil {
+		t.Logger("Installing drivers")
+		ok := MessageBox("Installing drivers", "We are about to install some drivers needed to use Arduino/Genuino boards\nDo you want to continue?")
+		if ok == OK_PRESSED {
+			os.Chdir(location)
+			t.Logger(preamble + "post_install" + extension)
+			oscmd := exec.Command(preamble + "post_install" + extension)
+			if runtime.GOOS != "linux" {
+				// spawning a shell could be the only way to let the user type his password
+				TellCommandNotToSpawnShell(oscmd)
+			}
+			err = oscmd.Run()
+			return err
+		} else {
+			return errors.New("Could not install drivers")
+		}
+	}
+	return nil
+}
+
 func makeExecutable(location string) error {
 	location = path.Join(location, "bin")
 	files, err := ioutil.ReadDir(location)
diff --git a/tools/download_test.go b/tools/download_test.go
index 74adefb44..4798ed854 100644
--- a/tools/download_test.go
+++ b/tools/download_test.go
@@ -2,6 +2,11 @@ package tools
 
 import (
 	"fmt"
+	"github.com/stretchr/testify/assert"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"path"
 	"testing"
 )
 
@@ -13,9 +18,16 @@ func Test_findBaseDir(t *testing.T) {
 		{[]string{"bin/bossac"}, "bin/"},
 		{[]string{"bin/", "bin/bossac"}, "bin/"},
 		{[]string{"bin/", "bin/bossac", "example"}, ""},
-		{[]string{"avrdude/bin/avrdude", "avrdude/etc/avrdude.conf"}, "avrdude/"},
-		{[]string{"pax_global_header","bin/", "bin/bossac"}, "bin/"},
-
+		{[]string{"avrdude/bin/",
+			"avrdude/bin/avrdude.exe",
+			"avrdude/bin/remove_giveio.bat",
+			"avrdude/bin/status_giveio.bat",
+			"avrdude/bin/giveio.sys",
+			"avrdude/bin/loaddrv.exe",
+			"avrdude/bin/libusb0.dll",
+			"avrdude/bin/install_giveio.bat",
+			"avrdude/etc/avrdude.conf"}, "avrdude/"},
+		{[]string{"pax_global_header", "bin/", "bin/bossac"}, "bin/"},
 	}
 	for _, tt := range cases {
 		t.Run(fmt.Sprintln(tt.dirList), func(t *testing.T) {
@@ -25,3 +37,67 @@ func Test_findBaseDir(t *testing.T) {
 		})
 	}
 }
+
+func TestTools_DownloadAndUnpackBehaviour(t *testing.T) {
+	urls := []string{
+		"http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-armhf-pc-linux-gnu.tar.bz2",
+		"http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-aarch64-pc-linux-gnu.tar.bz2",
+		"http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-i386-apple-darwin11.tar.bz2",
+		"http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-x86_64-pc-linux-gnu.tar.bz2",
+		"http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-i686-pc-linux-gnu.tar.bz2",
+		"http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-i686-w64-mingw32.zip",
+	}
+	expectedDirList := []string{"bin", "etc"}
+
+	for _, url := range urls {
+		t.Log("Downloading tool from " + url)
+		resp, err := http.Get(url)
+		if err != nil {
+			t.Errorf("%v", err)
+		}
+		defer resp.Body.Close()
+
+		// Read the body
+		body, err := ioutil.ReadAll(resp.Body)
+		if err != nil {
+			t.Errorf("%v", err)
+		}
+
+		location := path.Join("/tmp", dir(), "arduino", "avrdude", "6.3.0-arduino14")
+		os.MkdirAll(location, os.ModePerm)
+		err = os.RemoveAll(location)
+
+		if err != nil {
+			t.Errorf("%v", err)
+		}
+
+		srcType, err := mimeType(body)
+		if err != nil {
+			t.Errorf("%v", err)
+		}
+
+		switch srcType {
+		case "application/zip":
+			location, err = extractZip(func(msg string) { t.Log(msg) }, body, location)
+		case "application/x-bz2":
+		case "application/octet-stream":
+			location, err = extractBz2(func(msg string) { t.Log(msg) }, body, location)
+		case "application/x-gzip":
+			location, err = extractTarGz(func(msg string) { t.Log(msg) }, body, location)
+		default:
+			t.Errorf("no suitable type found")
+		}
+		files, err := ioutil.ReadDir(location)
+		if err != nil {
+			t.Errorf("%v", err)
+		}
+		dirList := []string{}
+		for _, f := range files {
+			dirList = append(dirList, f.Name())
+		}
+
+		assert.ElementsMatchf(t, dirList, expectedDirList, "error message %s", "formatted")
+
+	}
+
+}
diff --git a/vendor/github.com/Sirupsen/logrus/.gitignore b/vendor/github.com/Sirupsen/logrus/.gitignore
new file mode 100644
index 000000000..6b7d7d1e8
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/.gitignore
@@ -0,0 +1,2 @@
+logrus
+vendor
diff --git a/vendor/github.com/Sirupsen/logrus/.travis.yml b/vendor/github.com/Sirupsen/logrus/.travis.yml
new file mode 100644
index 000000000..1f953bebd
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/.travis.yml
@@ -0,0 +1,51 @@
+language: go
+env:
+  - GOMAXPROCS=4 GORACE=halt_on_error=1
+matrix:
+  include:
+    - go: 1.10.x
+      install:
+        - go get github.com/stretchr/testify/assert
+        - go get golang.org/x/crypto/ssh/terminal
+        - go get golang.org/x/sys/unix
+        - go get golang.org/x/sys/windows
+      script:
+        - go test -race -v ./...
+    - go: 1.11.x
+      env: GO111MODULE=on
+      install:
+        - go mod download
+      script:
+        - go test -race -v ./...
+    - go: 1.11.x
+      env: GO111MODULE=off
+      install:
+        - go get github.com/stretchr/testify/assert
+        - go get golang.org/x/crypto/ssh/terminal
+        - go get golang.org/x/sys/unix
+        - go get golang.org/x/sys/windows
+      script:
+        - go test -race -v ./...
+    - go: 1.10.x
+      install:
+        - go get github.com/stretchr/testify/assert
+        - go get golang.org/x/crypto/ssh/terminal
+        - go get golang.org/x/sys/unix
+        - go get golang.org/x/sys/windows
+      script:
+        - go test -race -v -tags appengine ./...
+    - go: 1.11.x
+      env: GO111MODULE=on
+      install:
+        - go mod download
+      script:
+        - go test -race -v -tags appengine ./...
+    - go: 1.11.x
+      env: GO111MODULE=off
+      install:
+        - go get github.com/stretchr/testify/assert
+        - go get golang.org/x/crypto/ssh/terminal
+        - go get golang.org/x/sys/unix
+        - go get golang.org/x/sys/windows
+      script:
+        - go test -race -v -tags appengine ./...
diff --git a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md
new file mode 100644
index 000000000..cb85d9f9f
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md
@@ -0,0 +1,165 @@
+# 1.2.0
+This new release introduces:
+  * A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
+  * A new trace level named `Trace` whose level is below `Debug`
+  * A configurable exit function to be called upon a Fatal trace
+  * The `Level` object now implements `encoding.TextUnmarshaler` interface
+
+# 1.1.1
+This is a bug fix release.
+  * fix the build break on Solaris
+  * don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized
+
+# 1.1.0
+This new release introduces:
+  * several fixes:
+    * a fix for a race condition on entry formatting
+    * proper cleanup of previously used entries before putting them back in the pool
+    * the extra new line at the end of message in text formatter has been removed
+  * a new global public API to check if a level is activated: IsLevelEnabled
+  * the following methods have been added to the Logger object
+    * IsLevelEnabled
+    * SetFormatter
+    * SetOutput
+    * ReplaceHooks
+  * introduction of go module
+  * an indent configuration for the json formatter
+  * output colour support for windows
+  * the field sort function is now configurable for text formatter
+  * the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater
+
+# 1.0.6
+
+This new release introduces:
+  * a new api WithTime which allows to easily force the time of the log entry
+    which is mostly useful for logger wrapper
+  * a fix reverting the immutability of the entry given as parameter to the hooks
+    a new configuration field of the json formatter in order to put all the fields
+    in a nested dictionnary
+  * a new SetOutput method in the Logger
+  * a new configuration of the textformatter to configure the name of the default keys
+  * a new configuration of the text formatter to disable the level truncation
+
+# 1.0.5
+
+* Fix hooks race (#707)
+* Fix panic deadlock (#695)
+
+# 1.0.4
+
+* Fix race when adding hooks (#612)
+* Fix terminal check in AppEngine (#635)
+
+# 1.0.3
+
+* Replace example files with testable examples
+
+# 1.0.2
+
+* bug: quote non-string values in text formatter (#583)
+* Make (*Logger) SetLevel a public method
+
+# 1.0.1
+
+* bug: fix escaping in text formatter (#575)
+
+# 1.0.0
+
+* Officially changed name to lower-case
+* bug: colors on Windows 10 (#541)
+* bug: fix race in accessing level (#512)
+
+# 0.11.5
+
+* feature: add writer and writerlevel to entry (#372)
+
+# 0.11.4
+
+* bug: fix undefined variable on solaris (#493)
+
+# 0.11.3
+
+* formatter: configure quoting of empty values (#484)
+* formatter: configure quoting character (default is `"`) (#484)
+* bug: fix not importing io correctly in non-linux environments (#481)
+
+# 0.11.2
+
+* bug: fix windows terminal detection (#476)
+
+# 0.11.1
+
+* bug: fix tty detection with custom out (#471)
+
+# 0.11.0
+
+* performance: Use bufferpool to allocate (#370)
+* terminal: terminal detection for app-engine (#343)
+* feature: exit handler (#375)
+
+# 0.10.0
+
+* feature: Add a test hook (#180)
+* feature: `ParseLevel` is now case-insensitive (#326)
+* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
+* performance: avoid re-allocations on `WithFields` (#335)
+
+# 0.9.0
+
+* logrus/text_formatter: don't emit empty msg
+* logrus/hooks/airbrake: move out of main repository
+* logrus/hooks/sentry: move out of main repository
+* logrus/hooks/papertrail: move out of main repository
+* logrus/hooks/bugsnag: move out of main repository
+* logrus/core: run tests with `-race`
+* logrus/core: detect TTY based on `stderr`
+* logrus/core: support `WithError` on logger
+* logrus/core: Solaris support
+
+# 0.8.7
+
+* logrus/core: fix possible race (#216)
+* logrus/doc: small typo fixes and doc improvements
+
+
+# 0.8.6
+
+* hooks/raven: allow passing an initialized client
+
+# 0.8.5
+
+* logrus/core: revert #208
+
+# 0.8.4
+
+* formatter/text: fix data race (#218)
+
+# 0.8.3
+
+* logrus/core: fix entry log level (#208)
+* logrus/core: improve performance of text formatter by 40%
+* logrus/core: expose `LevelHooks` type
+* logrus/core: add support for DragonflyBSD and NetBSD
+* formatter/text: print structs more verbosely
+
+# 0.8.2
+
+* logrus: fix more Fatal family functions
+
+# 0.8.1
+
+* logrus: fix not exiting on `Fatalf` and `Fatalln`
+
+# 0.8.0
+
+* logrus: defaults to stderr instead of stdout
+* hooks/sentry: add special field for `*http.Request`
+* formatter/text: ignore Windows for colors
+
+# 0.7.3
+
+* formatter/\*: allow configuration of timestamp layout
+
+# 0.7.2
+
+* formatter/text: Add configuration option for time format (#158)
diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/Sirupsen/logrus/README.md
new file mode 100644
index 000000000..093bb13f8
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/README.md
@@ -0,0 +1,493 @@
+# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>&nbsp;[![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus)&nbsp;[![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus)
+
+Logrus is a structured logger for Go (golang), completely API compatible with
+the standard library logger.
+
+**Seeing weird case-sensitive problems?** It's in the past been possible to
+import Logrus as both upper- and lower-case. Due to the Go package environment,
+this caused issues in the community and we needed a standard. Some environments
+experienced problems with the upper-case variant, so the lower-case was decided.
+Everything using `logrus` will need to use the lower-case:
+`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
+
+To fix Glide, see [these
+comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
+For an in-depth explanation of the casing issue, see [this
+comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
+
+**Are you interested in assisting in maintaining Logrus?** Currently I have a
+lot of obligations, and I am unable to provide Logrus with the maintainership it
+needs. If you'd like to help, please reach out to me at `simon at author's
+username dot com`.
+
+Nicely color-coded in development (when a TTY is attached, otherwise just
+plain text):
+
+![Colored](http://i.imgur.com/PY7qMwd.png)
+
+With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
+or Splunk:
+
+```json
+{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
+ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
+
+{"level":"warning","msg":"The group's number increased tremendously!",
+"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
+
+{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
+"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
+
+{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
+"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
+
+{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
+"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
+```
+
+With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
+attached, the output is compatible with the
+[logfmt](http://godoc.org/github.com/kr/logfmt) format:
+
+```text
+time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
+time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
+time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
+time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
+time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
+time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
+```
+To ensure this behaviour even if a TTY is attached, set your formatter as follows:
+
+```go
+	log.SetFormatter(&log.TextFormatter{
+		DisableColors: true,
+		FullTimestamp: true,
+	})
+```
+
+#### Logging Method Name
+
+If you wish to add the calling method as a field, instruct the logger via:
+```go
+log.SetReportCaller(true)
+```
+This adds the caller as 'method' like so:
+
+```json
+{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
+"time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
+```
+
+```text
+time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
+```
+Note that this does add measurable overhead - the cost will depend on the version of Go, but is
+between 20 and 40% in recent tests with 1.6 and 1.7.  You can validate this in your
+environment via benchmarks: 
+```
+go test -bench=.*CallerTracing
+```
+
+
+#### Case-sensitivity
+
+The organization's name was changed to lower-case--and this will not be changed
+back. If you are getting import conflicts due to case sensitivity, please use
+the lower-case import: `github.com/sirupsen/logrus`.
+
+#### Example
+
+The simplest way to use Logrus is simply the package-level exported logger:
+
+```go
+package main
+
+import (
+  log "github.com/sirupsen/logrus"
+)
+
+func main() {
+  log.WithFields(log.Fields{
+    "animal": "walrus",
+  }).Info("A walrus appears")
+}
+```
+
+Note that it's completely api-compatible with the stdlib logger, so you can
+replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
+and you'll now have the flexibility of Logrus. You can customize it all you
+want:
+
+```go
+package main
+
+import (
+  "os"
+  log "github.com/sirupsen/logrus"
+)
+
+func init() {
+  // Log as JSON instead of the default ASCII formatter.
+  log.SetFormatter(&log.JSONFormatter{})
+
+  // Output to stdout instead of the default stderr
+  // Can be any io.Writer, see below for File example
+  log.SetOutput(os.Stdout)
+
+  // Only log the warning severity or above.
+  log.SetLevel(log.WarnLevel)
+}
+
+func main() {
+  log.WithFields(log.Fields{
+    "animal": "walrus",
+    "size":   10,
+  }).Info("A group of walrus emerges from the ocean")
+
+  log.WithFields(log.Fields{
+    "omg":    true,
+    "number": 122,
+  }).Warn("The group's number increased tremendously!")
+
+  log.WithFields(log.Fields{
+    "omg":    true,
+    "number": 100,
+  }).Fatal("The ice breaks!")
+
+  // A common pattern is to re-use fields between logging statements by re-using
+  // the logrus.Entry returned from WithFields()
+  contextLogger := log.WithFields(log.Fields{
+    "common": "this is a common field",
+    "other": "I also should be logged always",
+  })
+
+  contextLogger.Info("I'll be logged with common and other field")
+  contextLogger.Info("Me too")
+}
+```
+
+For more advanced usage such as logging to multiple locations from the same
+application, you can also create an instance of the `logrus` Logger:
+
+```go
+package main
+
+import (
+  "os"
+  "github.com/sirupsen/logrus"
+)
+
+// Create a new instance of the logger. You can have any number of instances.
+var log = logrus.New()
+
+func main() {
+  // The API for setting attributes is a little different than the package level
+  // exported logger. See Godoc.
+  log.Out = os.Stdout
+
+  // You could set this to any `io.Writer` such as a file
+  // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
+  // if err == nil {
+  //  log.Out = file
+  // } else {
+  //  log.Info("Failed to log to file, using default stderr")
+  // }
+
+  log.WithFields(logrus.Fields{
+    "animal": "walrus",
+    "size":   10,
+  }).Info("A group of walrus emerges from the ocean")
+}
+```
+
+#### Fields
+
+Logrus encourages careful, structured logging through logging fields instead of
+long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
+to send event %s to topic %s with key %d")`, you should log the much more
+discoverable:
+
+```go
+log.WithFields(log.Fields{
+  "event": event,
+  "topic": topic,
+  "key": key,
+}).Fatal("Failed to send event")
+```
+
+We've found this API forces you to think about logging in a way that produces
+much more useful logging messages. We've been in countless situations where just
+a single added field to a log statement that was already there would've saved us
+hours. The `WithFields` call is optional.
+
+In general, with Logrus using any of the `printf`-family functions should be
+seen as a hint you should add a field, however, you can still use the
+`printf`-family functions with Logrus.
+
+#### Default Fields
+
+Often it's helpful to have fields _always_ attached to log statements in an
+application or parts of one. For example, you may want to always log the
+`request_id` and `user_ip` in the context of a request. Instead of writing
+`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on
+every line, you can create a `logrus.Entry` to pass around instead:
+
+```go
+requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
+requestLogger.Info("something happened on that request") # will log request_id and user_ip
+requestLogger.Warn("something not great happened")
+```
+
+#### Hooks
+
+You can add hooks for logging levels. For example to send errors to an exception
+tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
+multiple places simultaneously, e.g. syslog.
+
+Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
+`init`:
+
+```go
+import (
+  log "github.com/sirupsen/logrus"
+  "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
+  logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
+  "log/syslog"
+)
+
+func init() {
+
+  // Use the Airbrake hook to report errors that have Error severity or above to
+  // an exception tracker. You can create custom hooks, see the Hooks section.
+  log.AddHook(airbrake.NewHook(123, "xyz", "production"))
+
+  hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+  if err != nil {
+    log.Error("Unable to connect to local syslog daemon")
+  } else {
+    log.AddHook(hook)
+  }
+}
+```
+Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
+
+A list of currently known of service hook can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
+
+
+#### Level logging
+
+Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.
+
+```go
+log.Trace("Something very low level.")
+log.Debug("Useful debugging information.")
+log.Info("Something noteworthy happened!")
+log.Warn("You should probably take a look at this.")
+log.Error("Something failed but I'm not quitting.")
+// Calls os.Exit(1) after logging
+log.Fatal("Bye.")
+// Calls panic() after logging
+log.Panic("I'm bailing.")
+```
+
+You can set the logging level on a `Logger`, then it will only log entries with
+that severity or anything above it:
+
+```go
+// Will log anything that is info or above (warn, error, fatal, panic). Default.
+log.SetLevel(log.InfoLevel)
+```
+
+It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
+environment if your application has that.
+
+#### Entries
+
+Besides the fields added with `WithField` or `WithFields` some fields are
+automatically added to all logging events:
+
+1. `time`. The timestamp when the entry was created.
+2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
+   the `AddFields` call. E.g. `Failed to send event.`
+3. `level`. The logging level. E.g. `info`.
+
+#### Environments
+
+Logrus has no notion of environment.
+
+If you wish for hooks and formatters to only be used in specific environments,
+you should handle that yourself. For example, if your application has a global
+variable `Environment`, which is a string representation of the environment you
+could do:
+
+```go
+import (
+  log "github.com/sirupsen/logrus"
+)
+
+init() {
+  // do something here to set environment depending on an environment variable
+  // or command-line flag
+  if Environment == "production" {
+    log.SetFormatter(&log.JSONFormatter{})
+  } else {
+    // The TextFormatter is default, you don't actually have to do this.
+    log.SetFormatter(&log.TextFormatter{})
+  }
+}
+```
+
+This configuration is how `logrus` was intended to be used, but JSON in
+production is mostly only useful if you do log aggregation with tools like
+Splunk or Logstash.
+
+#### Formatters
+
+The built-in logging formatters are:
+
+* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
+  without colors.
+  * *Note:* to force colored output when there is no TTY, set the `ForceColors`
+    field to `true`.  To force no colored output even if there is a TTY  set the
+    `DisableColors` field to `true`. For Windows, see
+    [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
+  * When colors are enabled, levels are truncated to 4 characters by default. To disable
+    truncation set the `DisableLevelTruncation` field to `true`.
+  * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
+* `logrus.JSONFormatter`. Logs fields as JSON.
+  * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
+
+Third party logging formatters:
+
+* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
+* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
+* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
+* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
+
+You can define your formatter by implementing the `Formatter` interface,
+requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
+`Fields` type (`map[string]interface{}`) with all your fields as well as the
+default ones (see Entries section above):
+
+```go
+type MyJSONFormatter struct {
+}
+
+log.SetFormatter(new(MyJSONFormatter))
+
+func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
+  // Note this doesn't include Time, Level and Message which are available on
+  // the Entry. Consult `godoc` on information about those fields or read the
+  // source of the official loggers.
+  serialized, err := json.Marshal(entry.Data)
+    if err != nil {
+      return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
+    }
+  return append(serialized, '\n'), nil
+}
+```
+
+#### Logger as an `io.Writer`
+
+Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
+
+```go
+w := logger.Writer()
+defer w.Close()
+
+srv := http.Server{
+    // create a stdlib log.Logger that writes to
+    // logrus.Logger.
+    ErrorLog: log.New(w, "", 0),
+}
+```
+
+Each line written to that writer will be printed the usual way, using formatters
+and hooks. The level for those entries is `info`.
+
+This means that we can override the standard library logger easily:
+
+```go
+logger := logrus.New()
+logger.Formatter = &logrus.JSONFormatter{}
+
+// Use logrus for standard log output
+// Note that `log` here references stdlib's log
+// Not logrus imported under the name `log`.
+log.SetOutput(logger.Writer())
+```
+
+#### Rotation
+
+Log rotation is not provided with Logrus. Log rotation should be done by an
+external program (like `logrotate(8)`) that can compress and delete old log
+entries. It should not be a feature of the application-level logger.
+
+#### Tools
+
+| Tool | Description |
+| ---- | ----------- |
+|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
+|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
+
+#### Testing
+
+Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
+
+* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook
+* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
+
+```go
+import(
+  "github.com/sirupsen/logrus"
+  "github.com/sirupsen/logrus/hooks/test"
+  "github.com/stretchr/testify/assert"
+  "testing"
+)
+
+func TestSomething(t*testing.T){
+  logger, hook := test.NewNullLogger()
+  logger.Error("Helloerror")
+
+  assert.Equal(t, 1, len(hook.Entries))
+  assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
+  assert.Equal(t, "Helloerror", hook.LastEntry().Message)
+
+  hook.Reset()
+  assert.Nil(t, hook.LastEntry())
+}
+```
+
+#### Fatal handlers
+
+Logrus can register one or more functions that will be called when any `fatal`
+level message is logged. The registered handlers will be executed before
+logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need
+to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
+
+```
+...
+handler := func() {
+  // gracefully shutdown something...
+}
+logrus.RegisterExitHandler(handler)
+...
+```
+
+#### Thread safety
+
+By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs.
+If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
+
+Situation when locking is not needed includes:
+
+* You have no hooks registered, or hooks calling is already thread-safe.
+
+* Writing to logger.Out is already thread-safe, for example:
+
+  1) logger.Out is protected by locks.
+
+  2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing)
+
+     (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
diff --git a/vendor/github.com/Sirupsen/logrus/appveyor.yml b/vendor/github.com/Sirupsen/logrus/appveyor.yml
new file mode 100644
index 000000000..96c2ce15f
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/appveyor.yml
@@ -0,0 +1,14 @@
+version: "{build}"
+platform: x64
+clone_folder: c:\gopath\src\github.com\sirupsen\logrus
+environment:  
+  GOPATH: c:\gopath
+branches:  
+  only:
+    - master
+install:  
+  - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
+  - go version
+build_script:  
+  - go get -t
+  - go test
diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/Sirupsen/logrus/entry.go
index ca634a609..cc85d3aab 100644
--- a/vendor/github.com/Sirupsen/logrus/entry.go
+++ b/vendor/github.com/Sirupsen/logrus/entry.go
@@ -5,11 +5,29 @@ import (
 	"fmt"
 	"os"
 	"reflect"
+	"runtime"
+	"strings"
 	"sync"
 	"time"
 )
 
-var bufferPool *sync.Pool
+var (
+	bufferPool *sync.Pool
+
+	// qualified package name, cached at first use
+	logrusPackage string
+
+	// Positions in the call stack when tracing to report the calling method
+	minimumCallerDepth int
+
+	// Used for caller information initialisation
+	callerInitOnce sync.Once
+)
+
+const (
+	maximumCallerDepth int = 25
+	knownLogrusFrames  int = 4
+)
 
 func init() {
 	bufferPool = &sync.Pool{
@@ -17,15 +35,18 @@ func init() {
 			return new(bytes.Buffer)
 		},
 	}
+
+	// start at the bottom of the stack before the package-name cache is primed
+	minimumCallerDepth = 1
 }
 
 // Defines the key when adding errors using WithError.
 var ErrorKey = "error"
 
 // An entry is the final or intermediate Logrus logging entry. It contains all
-// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
-// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
-// passed around as much as you wish to avoid field duplication.
+// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
+// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
+// reused and passed around as much as you wish to avoid field duplication.
 type Entry struct {
 	Logger *Logger
 
@@ -35,11 +56,14 @@ type Entry struct {
 	// Time at which the log entry was created
 	Time time.Time
 
-	// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
+	// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
 	// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
 	Level Level
 
-	// Message passed to Debug, Info, Warn, Error, Fatal or Panic
+	// Calling method, with package name
+	Caller *runtime.Frame
+
+	// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
 	Message string
 
 	// When formatter is called in entry.log(), a Buffer may be set to entry
@@ -52,8 +76,8 @@ type Entry struct {
 func NewEntry(logger *Logger) *Entry {
 	return &Entry{
 		Logger: logger,
-		// Default is five fields, give a little extra room
-		Data: make(Fields, 5),
+		// Default is three fields, plus one optional.  Give a little extra room.
+		Data: make(Fields, 6),
 	}
 }
 
@@ -103,6 +127,57 @@ func (entry *Entry) WithTime(t time.Time) *Entry {
 	return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t}
 }
 
+// getPackageName reduces a fully qualified function name to the package name
+// There really ought to be to be a better way...
+func getPackageName(f string) string {
+	for {
+		lastPeriod := strings.LastIndex(f, ".")
+		lastSlash := strings.LastIndex(f, "/")
+		if lastPeriod > lastSlash {
+			f = f[:lastPeriod]
+		} else {
+			break
+		}
+	}
+
+	return f
+}
+
+// getCaller retrieves the name of the first non-logrus calling function
+func getCaller() *runtime.Frame {
+	// Restrict the lookback frames to avoid runaway lookups
+	pcs := make([]uintptr, maximumCallerDepth)
+	depth := runtime.Callers(minimumCallerDepth, pcs)
+	frames := runtime.CallersFrames(pcs[:depth])
+
+	// cache this package's fully-qualified name
+	callerInitOnce.Do(func() {
+		logrusPackage = getPackageName(runtime.FuncForPC(pcs[0]).Name())
+
+		// now that we have the cache, we can skip a minimum count of known-logrus functions
+		// XXX this is dubious, the number of frames may vary store an entry in a logger interface
+		minimumCallerDepth = knownLogrusFrames
+	})
+
+	for f, again := frames.Next(); again; f, again = frames.Next() {
+		pkg := getPackageName(f.Function)
+
+		// If the caller isn't part of this package, we're done
+		if pkg != logrusPackage {
+			return &f
+		}
+	}
+
+	// if we got here, we failed to find the caller's context
+	return nil
+}
+
+func (entry Entry) HasCaller() (has bool) {
+	return entry.Logger != nil &&
+		entry.Logger.ReportCaller &&
+		entry.Caller != nil
+}
+
 // This function is not declared with a pointer value because otherwise
 // race conditions will occur when using multiple goroutines
 func (entry Entry) log(level Level, msg string) {
@@ -119,6 +194,9 @@ func (entry Entry) log(level Level, msg string) {
 
 	entry.Level = level
 	entry.Message = msg
+	if entry.Logger.ReportCaller {
+		entry.Caller = getCaller()
+	}
 
 	entry.fireHooks()
 
@@ -162,6 +240,12 @@ func (entry *Entry) write() {
 	}
 }
 
+func (entry *Entry) Trace(args ...interface{}) {
+	if entry.Logger.IsLevelEnabled(TraceLevel) {
+		entry.log(TraceLevel, fmt.Sprint(args...))
+	}
+}
+
 func (entry *Entry) Debug(args ...interface{}) {
 	if entry.Logger.IsLevelEnabled(DebugLevel) {
 		entry.log(DebugLevel, fmt.Sprint(args...))
@@ -198,7 +282,7 @@ func (entry *Entry) Fatal(args ...interface{}) {
 	if entry.Logger.IsLevelEnabled(FatalLevel) {
 		entry.log(FatalLevel, fmt.Sprint(args...))
 	}
-	Exit(1)
+	entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panic(args ...interface{}) {
@@ -210,6 +294,12 @@ func (entry *Entry) Panic(args ...interface{}) {
 
 // Entry Printf family functions
 
+func (entry *Entry) Tracef(format string, args ...interface{}) {
+	if entry.Logger.IsLevelEnabled(TraceLevel) {
+		entry.Trace(fmt.Sprintf(format, args...))
+	}
+}
+
 func (entry *Entry) Debugf(format string, args ...interface{}) {
 	if entry.Logger.IsLevelEnabled(DebugLevel) {
 		entry.Debug(fmt.Sprintf(format, args...))
@@ -246,7 +336,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) {
 	if entry.Logger.IsLevelEnabled(FatalLevel) {
 		entry.Fatal(fmt.Sprintf(format, args...))
 	}
-	Exit(1)
+	entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panicf(format string, args ...interface{}) {
@@ -257,6 +347,12 @@ func (entry *Entry) Panicf(format string, args ...interface{}) {
 
 // Entry Println family functions
 
+func (entry *Entry) Traceln(args ...interface{}) {
+	if entry.Logger.IsLevelEnabled(TraceLevel) {
+		entry.Trace(entry.sprintlnn(args...))
+	}
+}
+
 func (entry *Entry) Debugln(args ...interface{}) {
 	if entry.Logger.IsLevelEnabled(DebugLevel) {
 		entry.Debug(entry.sprintlnn(args...))
@@ -293,7 +389,7 @@ func (entry *Entry) Fatalln(args ...interface{}) {
 	if entry.Logger.IsLevelEnabled(FatalLevel) {
 		entry.Fatal(entry.sprintlnn(args...))
 	}
-	Exit(1)
+	entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panicln(args ...interface{}) {
diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/Sirupsen/logrus/exported.go
index fb2a7a1f0..7342613c3 100644
--- a/vendor/github.com/Sirupsen/logrus/exported.go
+++ b/vendor/github.com/Sirupsen/logrus/exported.go
@@ -24,6 +24,12 @@ func SetFormatter(formatter Formatter) {
 	std.SetFormatter(formatter)
 }
 
+// SetReportCaller sets whether the standard logger will include the calling
+// method as a field.
+func SetReportCaller(include bool) {
+	std.SetReportCaller(include)
+}
+
 // SetLevel sets the standard logger level.
 func SetLevel(level Level) {
 	std.SetLevel(level)
@@ -77,6 +83,11 @@ func WithTime(t time.Time) *Entry {
 	return std.WithTime(t)
 }
 
+// Trace logs a message at level Trace on the standard logger.
+func Trace(args ...interface{}) {
+	std.Trace(args...)
+}
+
 // Debug logs a message at level Debug on the standard logger.
 func Debug(args ...interface{}) {
 	std.Debug(args...)
@@ -117,6 +128,11 @@ func Fatal(args ...interface{}) {
 	std.Fatal(args...)
 }
 
+// Tracef logs a message at level Trace on the standard logger.
+func Tracef(format string, args ...interface{}) {
+	std.Tracef(format, args...)
+}
+
 // Debugf logs a message at level Debug on the standard logger.
 func Debugf(format string, args ...interface{}) {
 	std.Debugf(format, args...)
@@ -157,6 +173,11 @@ func Fatalf(format string, args ...interface{}) {
 	std.Fatalf(format, args...)
 }
 
+// Traceln logs a message at level Trace on the standard logger.
+func Traceln(args ...interface{}) {
+	std.Traceln(args...)
+}
+
 // Debugln logs a message at level Debug on the standard logger.
 func Debugln(args ...interface{}) {
 	std.Debugln(args...)
diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/Sirupsen/logrus/formatter.go
index be2f3fcee..408883773 100644
--- a/vendor/github.com/Sirupsen/logrus/formatter.go
+++ b/vendor/github.com/Sirupsen/logrus/formatter.go
@@ -9,6 +9,8 @@ const (
 	FieldKeyLevel          = "level"
 	FieldKeyTime           = "time"
 	FieldKeyLogrusError    = "logrus_error"
+	FieldKeyFunc           = "func"
+	FieldKeyFile           = "file"
 )
 
 // The Formatter interface is used to implement a custom Formatter. It takes an
@@ -25,7 +27,7 @@ type Formatter interface {
 	Format(*Entry) ([]byte, error)
 }
 
-// This is to not silently overwrite `time`, `msg` and `level` fields when
+// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
 // dumping it. If this code wasn't there doing:
 //
 //  logrus.WithField("level", 1).Info("hello")
@@ -37,7 +39,7 @@ type Formatter interface {
 //
 // It's not exported because it's still using Data in an opinionated way. It's to
 // avoid code duplication between the two default formatters.
-func prefixFieldClashes(data Fields, fieldMap FieldMap) {
+func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
 	timeKey := fieldMap.resolve(FieldKeyTime)
 	if t, ok := data[timeKey]; ok {
 		data["fields."+timeKey] = t
@@ -61,4 +63,16 @@ func prefixFieldClashes(data Fields, fieldMap FieldMap) {
 		data["fields."+logrusErrKey] = l
 		delete(data, logrusErrKey)
 	}
+
+	// If reportCaller is not set, 'func' will not conflict.
+	if reportCaller {
+		funcKey := fieldMap.resolve(FieldKeyFunc)
+		if l, ok := data[funcKey]; ok {
+			data["fields."+funcKey] = l
+		}
+		fileKey := fieldMap.resolve(FieldKeyFile)
+		if l, ok := data[fileKey]; ok {
+			data["fields."+fileKey] = l
+		}
+	}
 }
diff --git a/vendor/github.com/Sirupsen/logrus/go.mod b/vendor/github.com/Sirupsen/logrus/go.mod
new file mode 100644
index 000000000..94574cc63
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/go.mod
@@ -0,0 +1,11 @@
+module github.com/sirupsen/logrus
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/konsorten/go-windows-terminal-sequences v1.0.1
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/objx v0.1.1 // indirect
+	github.com/stretchr/testify v1.2.2
+	golang.org/x/crypto v0.0.0-20180904163835-0709b304e793
+	golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33
+)
diff --git a/vendor/github.com/Sirupsen/logrus/go.sum b/vendor/github.com/Sirupsen/logrus/go.sum
new file mode 100644
index 000000000..133d34ae1
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/go.sum
@@ -0,0 +1,15 @@
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs=
+github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/Sirupsen/logrus/json_formatter.go
index ef8d07460..260575359 100644
--- a/vendor/github.com/Sirupsen/logrus/json_formatter.go
+++ b/vendor/github.com/Sirupsen/logrus/json_formatter.go
@@ -34,9 +34,10 @@ type JSONFormatter struct {
 	// As an example:
 	// formatter := &JSONFormatter{
 	//   	FieldMap: FieldMap{
-	// 		 FieldKeyTime: "@timestamp",
+	// 		 FieldKeyTime:  "@timestamp",
 	// 		 FieldKeyLevel: "@level",
-	// 		 FieldKeyMsg: "@message",
+	// 		 FieldKeyMsg:   "@message",
+	// 		 FieldKeyFunc:  "@caller",
 	//    },
 	// }
 	FieldMap FieldMap
@@ -47,7 +48,7 @@ type JSONFormatter struct {
 
 // Format renders a single log entry
 func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
-	data := make(Fields, len(entry.Data)+3)
+	data := make(Fields, len(entry.Data)+4)
 	for k, v := range entry.Data {
 		switch v := v.(type) {
 		case error:
@@ -65,7 +66,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
 		data = newData
 	}
 
-	prefixFieldClashes(data, f.FieldMap)
+	prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
 
 	timestampFormat := f.TimestampFormat
 	if timestampFormat == "" {
@@ -80,6 +81,10 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
 	}
 	data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
 	data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
+	if entry.HasCaller() {
+		data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
+		data[f.FieldMap.resolve(FieldKeyFile)] = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+	}
 
 	var b *bytes.Buffer
 	if entry.Buffer != nil {
diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/Sirupsen/logrus/logger.go
index b67bfcbd3..5ceca0eab 100644
--- a/vendor/github.com/Sirupsen/logrus/logger.go
+++ b/vendor/github.com/Sirupsen/logrus/logger.go
@@ -24,6 +24,10 @@ type Logger struct {
 	// own that implements the `Formatter` interface, see the `README` or included
 	// formatters for examples.
 	Formatter Formatter
+
+	// Flag for whether to log caller info (off by default)
+	ReportCaller bool
+
 	// The logging level the logger should log at. This is typically (and defaults
 	// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
 	// logged.
@@ -32,8 +36,12 @@ type Logger struct {
 	mu MutexWrap
 	// Reusable empty entry
 	entryPool sync.Pool
+	// Function to exit the application, defaults to `os.Exit()`
+	ExitFunc exitFunc
 }
 
+type exitFunc func(int)
+
 type MutexWrap struct {
 	lock     sync.Mutex
 	disabled bool
@@ -69,10 +77,12 @@ func (mw *MutexWrap) Disable() {
 // It's recommended to make this a global instance called `log`.
 func New() *Logger {
 	return &Logger{
-		Out:       os.Stderr,
-		Formatter: new(TextFormatter),
-		Hooks:     make(LevelHooks),
-		Level:     InfoLevel,
+		Out:          os.Stderr,
+		Formatter:    new(TextFormatter),
+		Hooks:        make(LevelHooks),
+		Level:        InfoLevel,
+		ExitFunc:     os.Exit,
+		ReportCaller: false,
 	}
 }
 
@@ -121,6 +131,14 @@ func (logger *Logger) WithTime(t time.Time) *Entry {
 	return entry.WithTime(t)
 }
 
+func (logger *Logger) Tracef(format string, args ...interface{}) {
+	if logger.IsLevelEnabled(TraceLevel) {
+		entry := logger.newEntry()
+		entry.Tracef(format, args...)
+		logger.releaseEntry(entry)
+	}
+}
+
 func (logger *Logger) Debugf(format string, args ...interface{}) {
 	if logger.IsLevelEnabled(DebugLevel) {
 		entry := logger.newEntry()
@@ -173,7 +191,7 @@ func (logger *Logger) Fatalf(format string, args ...interface{}) {
 		entry.Fatalf(format, args...)
 		logger.releaseEntry(entry)
 	}
-	Exit(1)
+	logger.Exit(1)
 }
 
 func (logger *Logger) Panicf(format string, args ...interface{}) {
@@ -184,6 +202,14 @@ func (logger *Logger) Panicf(format string, args ...interface{}) {
 	}
 }
 
+func (logger *Logger) Trace(args ...interface{}) {
+	if logger.IsLevelEnabled(TraceLevel) {
+		entry := logger.newEntry()
+		entry.Trace(args...)
+		logger.releaseEntry(entry)
+	}
+}
+
 func (logger *Logger) Debug(args ...interface{}) {
 	if logger.IsLevelEnabled(DebugLevel) {
 		entry := logger.newEntry()
@@ -236,7 +262,7 @@ func (logger *Logger) Fatal(args ...interface{}) {
 		entry.Fatal(args...)
 		logger.releaseEntry(entry)
 	}
-	Exit(1)
+	logger.Exit(1)
 }
 
 func (logger *Logger) Panic(args ...interface{}) {
@@ -247,6 +273,14 @@ func (logger *Logger) Panic(args ...interface{}) {
 	}
 }
 
+func (logger *Logger) Traceln(args ...interface{}) {
+	if logger.IsLevelEnabled(TraceLevel) {
+		entry := logger.newEntry()
+		entry.Traceln(args...)
+		logger.releaseEntry(entry)
+	}
+}
+
 func (logger *Logger) Debugln(args ...interface{}) {
 	if logger.IsLevelEnabled(DebugLevel) {
 		entry := logger.newEntry()
@@ -299,7 +333,7 @@ func (logger *Logger) Fatalln(args ...interface{}) {
 		entry.Fatalln(args...)
 		logger.releaseEntry(entry)
 	}
-	Exit(1)
+	logger.Exit(1)
 }
 
 func (logger *Logger) Panicln(args ...interface{}) {
@@ -310,6 +344,14 @@ func (logger *Logger) Panicln(args ...interface{}) {
 	}
 }
 
+func (logger *Logger) Exit(code int) {
+	runHandlers()
+	if logger.ExitFunc == nil {
+		logger.ExitFunc = os.Exit
+	}
+	logger.ExitFunc(code)
+}
+
 //When file is opened with appending mode, it's safe to
 //write concurrently to a file (within 4k message on Linux).
 //In these cases user can choose to disable the lock.
@@ -357,6 +399,12 @@ func (logger *Logger) SetOutput(output io.Writer) {
 	logger.Out = output
 }
 
+func (logger *Logger) SetReportCaller(reportCaller bool) {
+	logger.mu.Lock()
+	defer logger.mu.Unlock()
+	logger.ReportCaller = reportCaller
+}
+
 // ReplaceHooks replaces the logger hooks and returns the old ones
 func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
 	logger.mu.Lock()
diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/Sirupsen/logrus/logrus.go
index fa0b9dea8..4ef451866 100644
--- a/vendor/github.com/Sirupsen/logrus/logrus.go
+++ b/vendor/github.com/Sirupsen/logrus/logrus.go
@@ -15,6 +15,8 @@ type Level uint32
 // Convert the Level to a string. E.g. PanicLevel becomes "panic".
 func (level Level) String() string {
 	switch level {
+	case TraceLevel:
+		return "trace"
 	case DebugLevel:
 		return "debug"
 	case InfoLevel:
@@ -47,12 +49,26 @@ func ParseLevel(lvl string) (Level, error) {
 		return InfoLevel, nil
 	case "debug":
 		return DebugLevel, nil
+	case "trace":
+		return TraceLevel, nil
 	}
 
 	var l Level
 	return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
 }
 
+// UnmarshalText implements encoding.TextUnmarshaler.
+func (level *Level) UnmarshalText(text []byte) error {
+	l, err := ParseLevel(string(text))
+	if err != nil {
+		return err
+	}
+
+	*level = Level(l)
+
+	return nil
+}
+
 // A constant exposing all logging levels
 var AllLevels = []Level{
 	PanicLevel,
@@ -61,6 +77,7 @@ var AllLevels = []Level{
 	WarnLevel,
 	InfoLevel,
 	DebugLevel,
+	TraceLevel,
 }
 
 // These are the different logging levels. You can set the logging level to log
@@ -69,7 +86,7 @@ const (
 	// PanicLevel level, highest level of severity. Logs and then calls panic with the
 	// message passed to Debug, Info, ...
 	PanicLevel Level = iota
-	// FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
+	// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
 	// logging level is set to Panic.
 	FatalLevel
 	// ErrorLevel level. Logs. Used for errors that should definitely be noted.
@@ -82,6 +99,8 @@ const (
 	InfoLevel
 	// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
 	DebugLevel
+	// TraceLevel level. Designates finer-grained informational events than the Debug.
+	TraceLevel
 )
 
 // Won't compile if StdLogger can't be realized by a log.Logger
@@ -148,3 +167,12 @@ type FieldLogger interface {
 	// IsFatalEnabled() bool
 	// IsPanicEnabled() bool
 }
+
+// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
+// here for consistancy. Do not use. Use Logger or Entry instead.
+type Ext1FieldLogger interface {
+	FieldLogger
+	Tracef(format string, args ...interface{})
+	Trace(args ...interface{})
+	Traceln(args ...interface{})
+}
diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/Sirupsen/logrus/text_formatter.go
index d4663b8c2..49ec92f17 100644
--- a/vendor/github.com/Sirupsen/logrus/text_formatter.go
+++ b/vendor/github.com/Sirupsen/logrus/text_formatter.go
@@ -107,7 +107,7 @@ func (f *TextFormatter) isColored() bool {
 
 // Format renders a single log entry
 func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
-	prefixFieldClashes(entry.Data, f.FieldMap)
+	prefixFieldClashes(entry.Data, f.FieldMap, entry.HasCaller())
 
 	keys := make([]string, 0, len(entry.Data))
 	for k := range entry.Data {
@@ -125,6 +125,10 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
 	if entry.err != "" {
 		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
 	}
+	if entry.HasCaller() {
+		fixedKeys = append(fixedKeys,
+			f.FieldMap.resolve(FieldKeyFunc), f.FieldMap.resolve(FieldKeyFile))
+	}
 
 	if !f.DisableSorting {
 		if f.SortingFunc == nil {
@@ -160,15 +164,19 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
 	} else {
 		for _, key := range fixedKeys {
 			var value interface{}
-			switch key {
-			case f.FieldMap.resolve(FieldKeyTime):
+			switch {
+			case key == f.FieldMap.resolve(FieldKeyTime):
 				value = entry.Time.Format(timestampFormat)
-			case f.FieldMap.resolve(FieldKeyLevel):
+			case key == f.FieldMap.resolve(FieldKeyLevel):
 				value = entry.Level.String()
-			case f.FieldMap.resolve(FieldKeyMsg):
+			case key == f.FieldMap.resolve(FieldKeyMsg):
 				value = entry.Message
-			case f.FieldMap.resolve(FieldKeyLogrusError):
+			case key == f.FieldMap.resolve(FieldKeyLogrusError):
 				value = entry.err
+			case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
+				value = entry.Caller.Function
+			case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
+				value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
 			default:
 				value = entry.Data[key]
 			}
@@ -183,7 +191,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
 func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
 	var levelColor int
 	switch entry.Level {
-	case DebugLevel:
+	case DebugLevel, TraceLevel:
 		levelColor = gray
 	case WarnLevel:
 		levelColor = yellow
@@ -202,12 +210,19 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
 	// the behavior of logrus text_formatter the same as the stdlib log package
 	entry.Message = strings.TrimSuffix(entry.Message, "\n")
 
+	caller := ""
+
+	if entry.HasCaller() {
+		caller = fmt.Sprintf("%s:%d %s()",
+			entry.Caller.File, entry.Caller.Line, entry.Caller.Function)
+	}
+
 	if f.DisableTimestamp {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
 	} else if !f.FullTimestamp {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
 	} else {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
 	}
 	for _, k := range keys {
 		v := entry.Data[k]
diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/Sirupsen/logrus/writer.go
index 7bdebedc6..9e1f75135 100644
--- a/vendor/github.com/Sirupsen/logrus/writer.go
+++ b/vendor/github.com/Sirupsen/logrus/writer.go
@@ -24,6 +24,8 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
 	var printFunc func(args ...interface{})
 
 	switch level {
+	case TraceLevel:
+		printFunc = entry.Trace
 	case DebugLevel:
 		printFunc = entry.Debug
 	case InfoLevel:
diff --git a/vendor/github.com/blang/semver/.travis.yml b/vendor/github.com/blang/semver/.travis.yml
new file mode 100644
index 000000000..102fb9a69
--- /dev/null
+++ b/vendor/github.com/blang/semver/.travis.yml
@@ -0,0 +1,21 @@
+language: go
+matrix:
+  include:
+  - go: 1.4.3
+  - go: 1.5.4
+  - go: 1.6.3
+  - go: 1.7
+  - go: tip
+  allow_failures:
+  - go: tip
+install:
+- go get golang.org/x/tools/cmd/cover
+- go get github.com/mattn/goveralls
+script:
+- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci
+  -repotoken $COVERALLS_TOKEN
+- echo "Build examples" ; cd examples && go build
+- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .)
+env:
+  global:
+    secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw=
diff --git a/vendor/github.com/blang/semver/README.md b/vendor/github.com/blang/semver/README.md
new file mode 100644
index 000000000..08b2e4a3d
--- /dev/null
+++ b/vendor/github.com/blang/semver/README.md
@@ -0,0 +1,194 @@
+semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
+======
+
+semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
+
+Usage
+-----
+```bash
+$ go get github.com/blang/semver
+```
+Note: Always vendor your dependencies or fix on a specific version tag.
+
+```go
+import github.com/blang/semver
+v1, err := semver.Make("1.0.0-beta")
+v2, err := semver.Make("2.0.0-beta")
+v1.Compare(v2)
+```
+
+Also check the [GoDocs](http://godoc.org/github.com/blang/semver).
+
+Why should I use this lib?
+-----
+
+- Fully spec compatible
+- No reflection
+- No regex
+- Fully tested (Coverage >99%)
+- Readable parsing/validation errors
+- Fast (See [Benchmarks](#benchmarks))
+- Only Stdlib
+- Uses values instead of pointers
+- Many features, see below
+
+
+Features
+-----
+
+- Parsing and validation at all levels
+- Comparator-like comparisons
+- Compare Helper Methods
+- InPlace manipulation
+- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
+- Wildcards `>=1.x`, `<=2.5.x`
+- Sortable (implements sort.Interface)
+- database/sql compatible (sql.Scanner/Valuer)
+- encoding/json compatible (json.Marshaler/Unmarshaler)
+
+Ranges
+------
+
+A `Range` is a set of conditions which specify which versions satisfy the range.
+
+A condition is composed of an operator and a version. The supported operators are:
+
+- `<1.0.0` Less than `1.0.0`
+- `<=1.0.0` Less than or equal to `1.0.0`
+- `>1.0.0` Greater than `1.0.0`
+- `>=1.0.0` Greater than or equal to `1.0.0`
+- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
+- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
+
+Note that spaces between the operator and the version will be gracefully tolerated.
+
+A `Range` can link multiple `Ranges` separated by space:
+
+Ranges can be linked by logical AND:
+
+  - `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0`
+  - `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2`
+
+Ranges can also be linked by logical OR:
+
+  - `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x`
+
+AND has a higher precedence than OR. It's not possible to use brackets.
+
+Ranges can be combined by both AND and OR
+
+  - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
+
+Range usage:
+
+```
+v, err := semver.Parse("1.2.3")
+range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0")
+if range(v) {
+    //valid
+}
+
+```
+
+Example
+-----
+
+Have a look at full examples in [examples/main.go](examples/main.go)
+
+```go
+import github.com/blang/semver
+
+v, err := semver.Make("0.0.1-alpha.preview+123.github")
+fmt.Printf("Major: %d\n", v.Major)
+fmt.Printf("Minor: %d\n", v.Minor)
+fmt.Printf("Patch: %d\n", v.Patch)
+fmt.Printf("Pre: %s\n", v.Pre)
+fmt.Printf("Build: %s\n", v.Build)
+
+// Prerelease versions array
+if len(v.Pre) > 0 {
+    fmt.Println("Prerelease versions:")
+    for i, pre := range v.Pre {
+        fmt.Printf("%d: %q\n", i, pre)
+    }
+}
+
+// Build meta data array
+if len(v.Build) > 0 {
+    fmt.Println("Build meta data:")
+    for i, build := range v.Build {
+        fmt.Printf("%d: %q\n", i, build)
+    }
+}
+
+v001, err := semver.Make("0.0.1")
+// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
+v001.GT(v) == true
+v.LT(v001) == true
+v.GTE(v) == true
+v.LTE(v) == true
+
+// Or use v.Compare(v2) for comparisons (-1, 0, 1):
+v001.Compare(v) == 1
+v.Compare(v001) == -1
+v.Compare(v) == 0
+
+// Manipulate Version in place:
+v.Pre[0], err = semver.NewPRVersion("beta")
+if err != nil {
+    fmt.Printf("Error parsing pre release version: %q", err)
+}
+
+fmt.Println("\nValidate versions:")
+v.Build[0] = "?"
+
+err = v.Validate()
+if err != nil {
+    fmt.Printf("Validation failed: %s\n", err)
+}
+```
+
+
+Benchmarks
+-----
+
+    BenchmarkParseSimple-4           5000000    390    ns/op    48 B/op   1 allocs/op
+    BenchmarkParseComplex-4          1000000   1813    ns/op   256 B/op   7 allocs/op
+    BenchmarkParseAverage-4          1000000   1171    ns/op   163 B/op   4 allocs/op
+    BenchmarkStringSimple-4         20000000    119    ns/op    16 B/op   1 allocs/op
+    BenchmarkStringLarger-4         10000000    206    ns/op    32 B/op   2 allocs/op
+    BenchmarkStringComplex-4         5000000    324    ns/op    80 B/op   3 allocs/op
+    BenchmarkStringAverage-4         5000000    273    ns/op    53 B/op   2 allocs/op
+    BenchmarkValidateSimple-4      200000000      9.33 ns/op     0 B/op   0 allocs/op
+    BenchmarkValidateComplex-4       3000000    469    ns/op     0 B/op   0 allocs/op
+    BenchmarkValidateAverage-4       5000000    256    ns/op     0 B/op   0 allocs/op
+    BenchmarkCompareSimple-4       100000000     11.8  ns/op     0 B/op   0 allocs/op
+    BenchmarkCompareComplex-4       50000000     30.8  ns/op     0 B/op   0 allocs/op
+    BenchmarkCompareAverage-4       30000000     41.5  ns/op     0 B/op   0 allocs/op
+    BenchmarkSort-4                  3000000    419    ns/op   256 B/op   2 allocs/op
+    BenchmarkRangeParseSimple-4      2000000    850    ns/op   192 B/op   5 allocs/op
+    BenchmarkRangeParseAverage-4     1000000   1677    ns/op   400 B/op  10 allocs/op
+    BenchmarkRangeParseComplex-4      300000   5214    ns/op  1440 B/op  30 allocs/op
+    BenchmarkRangeMatchSimple-4     50000000     25.6  ns/op     0 B/op   0 allocs/op
+    BenchmarkRangeMatchAverage-4    30000000     56.4  ns/op     0 B/op   0 allocs/op
+    BenchmarkRangeMatchComplex-4    10000000    153    ns/op     0 B/op   0 allocs/op
+
+See benchmark cases at [semver_test.go](semver_test.go)
+
+
+Motivation
+-----
+
+I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.
+
+
+Contribution
+-----
+
+Feel free to make a pull request. For bigger changes create a issue first to discuss about it.
+
+
+License
+-----
+
+See [LICENSE](LICENSE) file.
diff --git a/vendor/github.com/blang/semver/package.json b/vendor/github.com/blang/semver/package.json
new file mode 100644
index 000000000..1cf8ebdd9
--- /dev/null
+++ b/vendor/github.com/blang/semver/package.json
@@ -0,0 +1,17 @@
+{
+  "author": "blang",
+  "bugs": {
+    "URL": "https://github.com/blang/semver/issues",
+    "url": "https://github.com/blang/semver/issues"
+  },
+  "gx": {
+    "dvcsimport": "github.com/blang/semver"
+  },
+  "gxVersion": "0.10.0",
+  "language": "go",
+  "license": "MIT",
+  "name": "semver",
+  "releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
+  "version": "3.5.1"
+}
+
diff --git a/vendor/github.com/creack/goselect/.gitignore b/vendor/github.com/creack/goselect/.gitignore
new file mode 100644
index 000000000..6f4dacea8
--- /dev/null
+++ b/vendor/github.com/creack/goselect/.gitignore
@@ -0,0 +1,29 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+
+go-select*
+goselect*
+example-*
+example/example
diff --git a/vendor/github.com/creack/goselect/Dockerfile b/vendor/github.com/creack/goselect/Dockerfile
new file mode 100644
index 000000000..d03b5a9d9
--- /dev/null
+++ b/vendor/github.com/creack/goselect/Dockerfile
@@ -0,0 +1,5 @@
+FROM		google/golang:stable
+MAINTAINER	Guillaume J. Charmes <guillaume@charmes.net>
+CMD		/tmp/a.out
+ADD		.	  /src
+RUN		cd /src && go build -o /tmp/a.out
diff --git a/vendor/github.com/creack/goselect/README.md b/vendor/github.com/creack/goselect/README.md
new file mode 100644
index 000000000..d5d06510e
--- /dev/null
+++ b/vendor/github.com/creack/goselect/README.md
@@ -0,0 +1,30 @@
+# go-select
+
+select(2) implementation in Go
+
+## Supported platforms
+
+|               | 386 | amd64 | arm | arm64 |
+|---------------|-----|-------|-----|-------|
+| **linux**     | yes | yes   | yes | yes   |
+| **darwin**    | yes | yes   | n/a | ??    |
+| **freebsd**   | yes | yes   | yes | ??    |
+| **openbsd**   | yes | yes   | yes | ??    |
+| **netbsd**    | yes | yes   | yes | ??    |
+| **dragonfly** | n/a | yes   | n/a | ??    |
+| **solaris**   | n/a | no    | n/a | ??    |
+| **plan9**     | no  | no    | n/a | ??    |
+| **windows**   | yes | yes   | n/a | ??    |
+| **android**   | n/a | n/a   | no  | ??    |
+
+*n/a: platform not supported by Go
+
+Go on `plan9` and `solaris` do not implement `syscall.Select` not `syscall.SYS_SELECT`.
+
+## Cross compile
+
+Using davecheney's https://github.com/davecheney/golang-crosscompile
+
+```
+export PLATFORMS="darwin/386 darwin/amd64 freebsd/386 freebsd/amd64 freebsd/arm linux/386 linux/amd64 linux/arm windows/386 windows/amd64 openbsd/386 openbsd/amd64 netbsd/386 netbsd/amd64 dragonfly/amd64 plan9/386 plan9/amd64 solaris/amd64"
+```
diff --git a/vendor/github.com/creack/goselect/test_crosscompile.sh b/vendor/github.com/creack/goselect/test_crosscompile.sh
new file mode 100755
index 000000000..533ca6647
--- /dev/null
+++ b/vendor/github.com/creack/goselect/test_crosscompile.sh
@@ -0,0 +1,17 @@
+export GOOS=linux;   export GOARCH=arm;   echo $GOOS/$GOARCH; go build
+export GOOS=linux;   export GOARCH=arm64; echo $GOOS/$GOARCH; go build
+export GOOS=linux;   export GOARCH=amd64; echo $GOOS/$GOARCH; go build
+export GOOS=linux;   export GOARCH=386;   echo $GOOS/$GOARCH; go build
+export GOOS=darwin;  export GOARCH=arm;   echo $GOOS/$GOARCH; go build
+export GOOS=darwin;  export GOARCH=arm64; echo $GOOS/$GOARCH; go build
+export GOOS=darwin;  export GOARCH=amd64; echo $GOOS/$GOARCH; go build
+export GOOS=darwin;  export GOARCH=386;   echo $GOOS/$GOARCH; go build
+export GOOS=freebsd; export GOARCH=arm;   echo $GOOS/$GOARCH; go build
+export GOOS=freebsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build
+export GOOS=freebsd; export GOARCH=386;   echo $GOOS/$GOARCH; go build
+export GOOS=openbsd; export GOARCH=arm;   echo $GOOS/$GOARCH; go build
+export GOOS=openbsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build
+export GOOS=openbsd; export GOARCH=386;   echo $GOOS/$GOARCH; go build
+export GOOS=netbsd;  export GOARCH=arm;   echo $GOOS/$GOARCH; go build
+export GOOS=netbsd;  export GOARCH=amd64; echo $GOOS/$GOARCH; go build
+export GOOS=netbsd;  export GOARCH=386;   echo $GOOS/$GOARCH; go build
diff --git a/vendor/github.com/davidmz/go-pageant/README.md b/vendor/github.com/davidmz/go-pageant/README.md
new file mode 100644
index 000000000..23a352e41
--- /dev/null
+++ b/vendor/github.com/davidmz/go-pageant/README.md
@@ -0,0 +1,9 @@
+[![GoDoc](https://godoc.org/github.com/davidmz/go-pageant?status.svg)](https://godoc.org/github.com/davidmz/go-pageant)
+
+Package pageant provides an interface to PyTTY pageant.exe utility.
+
+This package is windows-only.
+
+See documentation on [GoDoc](http://godoc.org/github.com/davidmz/go-pageant)
+
+License: MIT
\ No newline at end of file
diff --git a/vendor/github.com/getlantern/context/.travis.yml b/vendor/github.com/getlantern/context/.travis.yml
new file mode 100644
index 000000000..cc2835a08
--- /dev/null
+++ b/vendor/github.com/getlantern/context/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+
+go:
+  - 1.6.2
+
+install:
+  - go get -d -t -v ./...
+  - go build -v ./...
+  - go get golang.org/x/tools/cmd/cover
+  - go get -v github.com/axw/gocov/gocov
+  - go get -v github.com/mattn/goveralls
+
+script:
+  - go test -race -v -covermode=atomic -coverprofile=profile.cov
+  - $HOME/gopath/bin/goveralls -coverprofile=profile.cov -service=travis-ci
diff --git a/vendor/github.com/getlantern/context/README.md b/vendor/github.com/getlantern/context/README.md
new file mode 100644
index 000000000..978c9e05a
--- /dev/null
+++ b/vendor/github.com/getlantern/context/README.md
@@ -0,0 +1,6 @@
+# context [![Travis CI Status](https://travis-ci.org/getlantern/context.svg?branch=master)](https://travis-ci.org/getlantern/context)&nbsp;[![Coverage Status](https://coveralls.io/repos/getlantern/context/badge.png?branch=master)](https://coveralls.io/r/getlantern/context) 
+
+Provides goroutine-based context state inspired by https://github.com/tylerb/gls
+and https://github.com/jtolds/gls. It uses the same basic hack as tylerb's
+library, but adds a stack abstraction that allows nested contexts similar to
+jtolds' library, but using `Enter()` and `Exit()` instead of callback functions.
diff --git a/vendor/github.com/getlantern/context/context.go b/vendor/github.com/getlantern/context/context.go
index d84e35770..2a9cc33ad 100644
--- a/vendor/github.com/getlantern/context/context.go
+++ b/vendor/github.com/getlantern/context/context.go
@@ -16,11 +16,13 @@ type Manager interface {
 	// the current goroutine (if it has one).
 	Go(func())
 
-	// PutGlobal puts the given key->value pair into the globalc context.
+	// PutGlobal puts the given key->value pair into the global context.
 	PutGlobal(key string, value interface{})
 
-	// PutGlobalDynamic puts a key->value pair into the global context wwhere the value is
-	// generated by a function that gets evaluated at every Read.
+	// PutGlobalDynamic puts a key->value pair into the global context where the
+	// value is generated by a function that gets evaluated at every Read. If the
+	// value is a map[string]interface{}, we will unpack the map and set each
+	// contained key->value pair independently.
 	PutGlobalDynamic(key string, valueFN func() interface{})
 
 	// AsMap returns a map containing all values from the supplied obj if it is a
@@ -78,8 +80,10 @@ type Context interface {
 	// stack (including parent contexts).
 	PutIfAbsent(key string, value interface{}) Context
 
-	// PutDynamic puts a key->value pair into the current level of the context stack
-	// where the value is generated by a function that gets evaluated at every Read.
+	// PutDynamic puts a key->value pair into the current level of the context
+	// stack where the value is generated by a function that gets evaluated at
+	// every Read. If the value is a map[string]interface{}, we will unpack the
+	// map and set each contained key->value pair independently.
 	PutDynamic(key string, valueFN func() interface{}) Context
 
 	// Fill fills the given map with data from this Context
@@ -266,14 +270,25 @@ func (c *context) asMap(cm *manager, obj interface{}, includeGlobals bool) Map {
 
 func fill(m Map, from Map) {
 	if m != nil {
+		doFill := func(key string, _value interface{}) {
+			switch value := _value.(type) {
+			case map[string]interface{}:
+				for k, v := range value {
+					m[k] = v
+				}
+			default:
+				m[key] = value
+			}
+		}
+
 		for key, value := range from {
 			_, alreadyRead := m[key]
 			if !alreadyRead {
 				switch v := value.(type) {
 				case *dynval:
-					m[key] = v.fn()
+					doFill(key, v.fn())
 				default:
-					m[key] = v
+					doFill(key, v)
 				}
 			}
 		}
diff --git a/vendor/github.com/getlantern/golog/.travis.yml b/vendor/github.com/getlantern/golog/.travis.yml
new file mode 100644
index 000000000..ab6a7f91b
--- /dev/null
+++ b/vendor/github.com/getlantern/golog/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+
+go:
+  - 1.4.1
+
+install:
+  - go get -d -t -v ./...
+  - go build -v ./...
+  - go get golang.org/x/tools/cmd/cover
+  - go get -v github.com/axw/gocov/gocov
+  - go get -v github.com/mattn/goveralls
+
+script:
+  - $HOME/gopath/bin/goveralls -v -service travis-ci github.com/getlantern/golog
\ No newline at end of file
diff --git a/vendor/github.com/getlantern/golog/README.md b/vendor/github.com/getlantern/golog/README.md
new file mode 100644
index 000000000..88fe677d1
--- /dev/null
+++ b/vendor/github.com/getlantern/golog/README.md
@@ -0,0 +1,6 @@
+golog [![Travis CI Status](https://travis-ci.org/getlantern/golog.svg?branch=master)](https://travis-ci.org/getlantern/golog)&nbsp;[![Coverage Status](https://coveralls.io/repos/getlantern/golog/badge.png)](https://coveralls.io/r/getlantern/golog)&nbsp;[![GoDoc](https://godoc.org/github.com/getlantern/golog?status.png)](http://godoc.org/github.com/getlantern/golog)
+==========
+Provides logging used in many getlantern components.
+
+[GoDoc](https://godoc.org/github.com/getlantern/golog)
+
diff --git a/vendor/github.com/getlantern/systray/.gitignore b/vendor/github.com/getlantern/systray/.gitignore
new file mode 100644
index 000000000..ae7e06bd5
--- /dev/null
+++ b/vendor/github.com/getlantern/systray/.gitignore
@@ -0,0 +1,11 @@
+example/example
+*~
+*.swp
+*.exe
+Release
+Debug
+*.sdf
+dll/systray_unsigned.dll
+out.txt
+.vs
+on_exit*.txt
diff --git a/vendor/github.com/getlantern/systray/README.md b/vendor/github.com/getlantern/systray/README.md
new file mode 100644
index 000000000..626c132b1
--- /dev/null
+++ b/vendor/github.com/getlantern/systray/README.md
@@ -0,0 +1,50 @@
+Package systray is a cross platfrom Go library to place an icon and menu in the notification area.
+Tested on Windows 8, Mac OSX, Ubuntu 14.10 and Debian 7.6.
+
+## Usage
+```go
+func main() {
+	// Should be called at the very beginning of main().
+	systray.Run(onReady, onExit)
+}
+
+func onReady() {
+	systray.SetIcon(icon.Data)
+	systray.SetTitle("Awesome App")
+	systray.SetTooltip("Pretty awesome超级棒")
+	mQuit := systray.AddMenuItem("Quit", "Quit the whole app")
+
+	// Sets the icon of a menu item. Only available on Mac.
+	mQuit.SetIcon(icon.Data)
+}
+
+func onExit() {
+	// clean up here
+}
+```
+Menu item can be checked and / or disabled. Methods except `Run()` can be invoked from any goroutine. See demo code under `example` folder.
+
+## Platform specific concerns
+
+### Linux
+
+```sh
+sudo apt-get install libgtk-3-dev libappindicator3-dev
+```
+Checked menu item not implemented on Linux yet.
+
+## Try
+
+Under `example` folder.
+Place tray icon under `icon`, and use `make_icon.bat` or `make_icon.sh`, whichever suit for your os, to convert the icon to byte array.
+Your icon should be .ico file under Windows, whereas .ico, .jpg and .png is supported on other platform.
+
+```sh
+go get
+go run main.go
+```
+
+## Credits
+
+- https://github.com/xilp/systray
+- https://github.com/cratonica/trayhost
diff --git a/vendor/github.com/getlantern/systray/systray_darwin.m b/vendor/github.com/getlantern/systray/systray_darwin.m
index e46694882..a489bc477 100644
--- a/vendor/github.com/getlantern/systray/systray_darwin.m
+++ b/vendor/github.com/getlantern/systray/systray_darwin.m
@@ -64,30 +64,15 @@ - (void)applicationWillTerminate:(NSNotification *)aNotification
 }
 
 - (void)setIcon:(NSImage *)image {
-  statusItem.button.image = image;
-  [self updateTitleButtonStyle];
+  [statusItem setImage:image];
 }
 
 - (void)setTitle:(NSString *)title {
-  statusItem.button.title = title;
-  [self updateTitleButtonStyle];
+  [statusItem setTitle:title];
 }
 
--(void)updateTitleButtonStyle {
-  if (statusItem.button.image != nil) {
-    if ([statusItem.button.title length] == 0) {
-      statusItem.button.imagePosition = NSImageOnly;
-    } else {
-      statusItem.button.imagePosition = NSImageLeft;
-    }
-  } else {
-    statusItem.button.imagePosition = NSNoImage;
-  }
-}
-
-
 - (void)setTooltip:(NSString *)tooltip {
-  statusItem.button.toolTip = tooltip;
+  [statusItem setToolTip:tooltip];
 }
 
 - (IBAction)menuHandler:(id)sender
@@ -112,14 +97,14 @@ - (void) add_or_update_menu_item:(MenuItem*) item
   }
   [menuItem setToolTip:item->tooltip];
   if (item->disabled == 1) {
-    menuItem.enabled = FALSE;
+    [menuItem setEnabled:FALSE];
   } else {
-    menuItem.enabled = TRUE;
+    [menuItem setEnabled:TRUE];
   }
   if (item->checked == 1) {
-    menuItem.state = NSControlStateValueOn;
+    [menuItem setState:NSOnState];
   } else {
-    menuItem.state = NSControlStateValueOff;
+    [menuItem setState:NSOffState];
   }
 }
 
diff --git a/vendor/github.com/getlantern/systray/systray_linux.c b/vendor/github.com/getlantern/systray/systray_linux.c
index 72cd6140f..a34c2672a 100644
--- a/vendor/github.com/getlantern/systray/systray_linux.c
+++ b/vendor/github.com/getlantern/systray/systray_linux.c
@@ -8,7 +8,8 @@
 static AppIndicator *global_app_indicator;
 static GtkWidget *global_tray_menu = NULL;
 static GList *global_menu_items = NULL;
-static char temp_file_name[PATH_MAX] = "";
+// Keep track of all generated temp files to remove when app quits
+static GArray *global_temp_icon_file_names = NULL;
 
 typedef struct {
 	GtkWidget *menu_item;
@@ -30,39 +31,24 @@ int nativeLoop(void) {
 	app_indicator_set_status(global_app_indicator, APP_INDICATOR_STATUS_ACTIVE);
 	global_tray_menu = gtk_menu_new();
 	app_indicator_set_menu(global_app_indicator, GTK_MENU(global_tray_menu));
+	global_temp_icon_file_names = g_array_new(TRUE, FALSE, sizeof(char*));
 	systray_ready();
 	gtk_main();
 	systray_on_exit();
 	return 0;
 }
 
-void _unlink_temp_file() {
-	if (strlen(temp_file_name) != 0) {
-		int ret = unlink(temp_file_name);
-		if (ret == -1) {
-			printf("failed to remove temp icon file %s: %s\n", temp_file_name, strerror(errno));
-		}
-		temp_file_name[0] = '\0';
-	}
-}
-
 // runs in main thread, should always return FALSE to prevent gtk to execute it again
 gboolean do_set_icon(gpointer data) {
-	_unlink_temp_file();
-	char *tmpdir = getenv("TMPDIR");
-	if (NULL == tmpdir) {
-		tmpdir = "/tmp";
-	}
-	strncpy(temp_file_name, tmpdir, PATH_MAX-1);
-	strncat(temp_file_name, "/systray_XXXXXX", PATH_MAX-1);
-	temp_file_name[PATH_MAX-1] = '\0';
-
 	GBytes* bytes = (GBytes*)data;
+	char* temp_file_name = malloc(PATH_MAX);
+	strcpy(temp_file_name, "/tmp/systray_XXXXXX");
 	int fd = mkstemp(temp_file_name);
 	if (fd == -1) {
 		printf("failed to create temp icon file %s: %s\n", temp_file_name, strerror(errno));
 		return FALSE;
 	}
+	g_array_append_val(global_temp_icon_file_names, temp_file_name);
 	gsize size = 0;
 	gconstpointer icon_data = g_bytes_get_data(bytes, &size);
 	ssize_t written = write(fd, icon_data, size);
@@ -160,7 +146,17 @@ gboolean do_show_menu_item(gpointer data) {
 
 // runs in main thread, should always return FALSE to prevent gtk to execute it again
 gboolean do_quit(gpointer data) {
-	_unlink_temp_file();
+	int i;
+	for (i = 0; i < INT_MAX; ++i) {
+		char * temp_file_name = g_array_index(global_temp_icon_file_names, char*, i);
+		if (temp_file_name == NULL) {
+			break;
+		}
+		int ret = unlink(temp_file_name);
+		if (ret == -1) {
+			printf("failed to remove temp icon file %s: %s\n", temp_file_name, strerror(errno));
+		}
+	}
 	// app indicator doesn't provide a way to remove it, hide it as a workaround
 	app_indicator_set_status(global_app_indicator, APP_INDICATOR_STATUS_PASSIVE);
 	gtk_main_quit();
diff --git a/vendor/github.com/getlantern/systray/systray_windows.go b/vendor/github.com/getlantern/systray/systray_windows.go
index 26a0f8074..7a9d7a17a 100644
--- a/vendor/github.com/getlantern/systray/systray_windows.go
+++ b/vendor/github.com/getlantern/systray/systray_windows.go
@@ -8,7 +8,6 @@ import (
 	"io/ioutil"
 	"os"
 	"path/filepath"
-	"syscall"
 	"unsafe"
 
 	"golang.org/x/sys/windows"
@@ -464,10 +463,8 @@ func (t *winTray) addOrUpdateMenuItem(menuId int32, title string, disabled, chec
 
 	// The return value is the identifier of the specified menu item.
 	// If the menu item identifier is NULL or if the specified item opens a submenu, the return value is -1.
-	// If the given menu identifier is not found (becase we deleted the menu item when hiding it),
-	// the call will return the next integer that is available as an existing menu item.
 	res, _, err := pGetMenuItemID.Call(uintptr(t.menu), uintptr(menuId))
-	if int32(res) == -1 || int32(res) != menuId {
+	if int32(res) == -1 {
 		res, _, err = pInsertMenuItem.Call(
 			uintptr(t.menu),
 			uintptr(menuId),
@@ -525,14 +522,13 @@ func (t *winTray) addSeparatorMenuItem(menuId int32) error {
 func (t *winTray) hideMenuItem(menuId int32) error {
 	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647629(v=vs.85).aspx
 	const MF_BYCOMMAND = 0x00000000
-	const ERROR_SUCCESS syscall.Errno = 0
 
 	res, _, err := pDeleteMenu.Call(
 		uintptr(t.menu),
 		uintptr(uint32(menuId)),
 		MF_BYCOMMAND,
 	)
-	if res == 0 && err.(syscall.Errno) != ERROR_SUCCESS {
+	if res == 0 {
 		return err
 	}
 
diff --git a/vendor/github.com/gin-contrib/sse/.travis.yml b/vendor/github.com/gin-contrib/sse/.travis.yml
new file mode 100644
index 000000000..a556ac09e
--- /dev/null
+++ b/vendor/github.com/gin-contrib/sse/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+sudo: false
+go:
+  - 1.6.4
+  - 1.7.4
+  - tip
+
+git:
+  depth: 3
+
+script:
+  - go test -v -covermode=count -coverprofile=coverage.out
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
diff --git a/vendor/github.com/gin-contrib/sse/README.md b/vendor/github.com/gin-contrib/sse/README.md
new file mode 100644
index 000000000..c9c49cf94
--- /dev/null
+++ b/vendor/github.com/gin-contrib/sse/README.md
@@ -0,0 +1,58 @@
+# Server-Sent Events
+
+[![GoDoc](https://godoc.org/github.com/gin-contrib/sse?status.svg)](https://godoc.org/github.com/gin-contrib/sse)
+[![Build Status](https://travis-ci.org/gin-contrib/sse.svg)](https://travis-ci.org/gin-contrib/sse)
+[![codecov](https://codecov.io/gh/gin-contrib/sse/branch/master/graph/badge.svg)](https://codecov.io/gh/gin-contrib/sse)
+[![Go Report Card](https://goreportcard.com/badge/github.com/gin-contrib/sse)](https://goreportcard.com/report/github.com/gin-contrib/sse)
+
+Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection. The Server-Sent Events EventSource API is [standardized as part of HTML5[1] by the W3C](http://www.w3.org/TR/2009/WD-eventsource-20091029/).
+
+- [Read this great SSE introduction by the HTML5Rocks guys](http://www.html5rocks.com/en/tutorials/eventsource/basics/)
+- [Browser support](http://caniuse.com/#feat=eventsource)
+
+## Sample code
+
+```go
+import "github.com/gin-contrib/sse"
+
+func httpHandler(w http.ResponseWriter, req *http.Request) {
+	// data can be a primitive like a string, an integer or a float
+	sse.Encode(w, sse.Event{
+		Event: "message",
+		Data:  "some data\nmore data",
+	})
+
+	// also a complex type, like a map, a struct or a slice
+	sse.Encode(w, sse.Event{
+		Id:    "124",
+		Event: "message",
+		Data: map[string]interface{}{
+			"user":    "manu",
+			"date":    time.Now().Unix(),
+			"content": "hi!",
+		},
+	})
+}
+```
+```
+event: message
+data: some data\\nmore data
+
+id: 124
+event: message
+data: {"content":"hi!","date":1431540810,"user":"manu"}
+ 
+```
+
+## Content-Type
+
+```go
+fmt.Println(sse.ContentType)
+```
+```
+text/event-stream
+```
+
+## Decoding support
+
+There is a client-side implementation of SSE coming soon.
diff --git a/vendor/github.com/gin-gonic/gin/.gitignore b/vendor/github.com/gin-gonic/gin/.gitignore
new file mode 100644
index 000000000..14dc8f20d
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/.gitignore
@@ -0,0 +1,5 @@
+vendor/*
+!vendor/vendor.json
+coverage.out
+count.out
+test
diff --git a/vendor/github.com/gin-gonic/gin/.travis.yml b/vendor/github.com/gin-gonic/gin/.travis.yml
new file mode 100644
index 000000000..e91015685
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/.travis.yml
@@ -0,0 +1,35 @@
+language: go
+sudo: false
+go:
+  - 1.6.x
+  - 1.7.x
+  - 1.8.x
+  - 1.9.x
+  - 1.10.x
+  - master
+
+git:
+  depth: 10
+
+install:
+  - make install
+
+go_import_path: github.com/gin-gonic/gin
+
+script:
+  - make vet
+  - make fmt-check
+  - make embedmd
+  - make misspell-check
+  - make test
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+  webhooks:
+    urls:
+      - https://webhooks.gitter.im/e/7f95bf605c4d356372f4
+    on_success: change  # options: [always|never|change] default: always
+    on_failure: always  # options: [always|never|change] default: always
+    on_start: false     # default: false
diff --git a/vendor/github.com/gin-gonic/gin/BENCHMARKS.md b/vendor/github.com/gin-gonic/gin/BENCHMARKS.md
new file mode 100644
index 000000000..9a7df86a3
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/BENCHMARKS.md
@@ -0,0 +1,604 @@
+
+## Benchmark System
+
+**VM HOST:** DigitalOcean  
+**Machine:** 4 CPU, 8 GB RAM. Ubuntu 16.04.2 x64  
+**Date:** July 19th, 2017  
+**Go Version:** 1.8.3 linux/amd64  
+**Source:** [Go HTTP Router Benchmark](https://github.com/julienschmidt/go-http-routing-benchmark)  
+
+## Static Routes: 157
+
+```
+Gin:             30512 Bytes
+
+HttpServeMux:    17344 Bytes
+Ace:             30080 Bytes
+Bear:            30472 Bytes
+Beego:           96408 Bytes
+Bone:            37904 Bytes
+Denco:           10464 Bytes
+Echo:            73680 Bytes
+GocraftWeb:      55720 Bytes
+Goji:            27200 Bytes
+Gojiv2:         104464 Bytes
+GoJsonRest:     136472 Bytes
+GoRestful:      914904 Bytes
+GorillaMux:     675568 Bytes
+HttpRouter:      21128 Bytes
+HttpTreeMux:     73448 Bytes
+Kocha:          115072 Bytes
+LARS:            30120 Bytes
+Macaron:         37984 Bytes
+Martini:        310832 Bytes
+Pat:             20464 Bytes
+Possum:          91328 Bytes
+R2router:        23712 Bytes
+Rivet:           23880 Bytes
+Tango:           28008 Bytes
+TigerTonic:      80368 Bytes
+Traffic:        626480 Bytes
+Vulcan:         369064 Bytes
+```
+
+## GithubAPI Routes: 203
+
+```
+Gin:             52672 Bytes
+
+Ace:             48992 Bytes
+Bear:           161592 Bytes
+Beego:          147992 Bytes
+Bone:            97728 Bytes
+Denco:           36440 Bytes
+Echo:            95672 Bytes
+GocraftWeb:      95640 Bytes
+Goji:            86088 Bytes
+Gojiv2:         144392 Bytes
+GoJsonRest:     134648 Bytes
+GoRestful:     1410760 Bytes
+GorillaMux:    1509488 Bytes
+HttpRouter:      37464 Bytes
+HttpTreeMux:     78800 Bytes
+Kocha:          785408 Bytes
+LARS:            49032 Bytes
+Macaron:        132712 Bytes
+Martini:        564352 Bytes
+Pat:             21200 Bytes
+Possum:          83888 Bytes
+R2router:        47104 Bytes
+Rivet:           42840 Bytes
+Tango:           54584 Bytes
+TigerTonic:      96384 Bytes
+Traffic:       1061920 Bytes
+Vulcan:         465296 Bytes
+```
+
+## GPlusAPI Routes: 13
+
+```
+Gin:              3968 Bytes
+
+Ace:              3600 Bytes
+Bear:             7112 Bytes
+Beego:           10048 Bytes
+Bone:             6480 Bytes
+Denco:            3256 Bytes
+Echo:             9000 Bytes
+GocraftWeb:       7496 Bytes
+Goji:             2912 Bytes
+Gojiv2:           7376 Bytes
+GoJsonRest:      11544 Bytes
+GoRestful:       88776 Bytes
+GorillaMux:      71488 Bytes
+HttpRouter:       2712 Bytes
+HttpTreeMux:      7440 Bytes
+Kocha:          128880 Bytes
+LARS:             3640 Bytes
+Macaron:          8656 Bytes
+Martini:         23936 Bytes
+Pat:              1856 Bytes
+Possum:           7248 Bytes
+R2router:         3928 Bytes
+Rivet:            3064 Bytes
+Tango:            4912 Bytes
+TigerTonic:       9408 Bytes
+Traffic:         49472 Bytes
+Vulcan:          25496 Bytes
+```
+
+## ParseAPI Routes: 26
+
+```
+Gin:              6928 Bytes
+
+Ace:              6592 Bytes
+Bear:            12320 Bytes
+Beego:           18960 Bytes
+Bone:            11024 Bytes
+Denco:            4184 Bytes
+Echo:            11168 Bytes
+GocraftWeb:      12800 Bytes
+Goji:             5232 Bytes
+Gojiv2:          14464 Bytes
+GoJsonRest:      14216 Bytes
+GoRestful:      127368 Bytes
+GorillaMux:     123016 Bytes
+HttpRouter:       4976 Bytes
+HttpTreeMux:      7848 Bytes
+Kocha:          181712 Bytes
+LARS:             6632 Bytes
+Macaron:         13648 Bytes
+Martini:         45952 Bytes
+Pat:              2560 Bytes
+Possum:           9200 Bytes
+R2router:         7056 Bytes
+Rivet:            5680 Bytes
+Tango:            8664 Bytes
+TigerTonic:       9840 Bytes
+Traffic:         93480 Bytes
+Vulcan:          44504 Bytes
+```
+
+## Static Routes
+
+```
+BenchmarkGin_StaticAll                     50000             34506 ns/op               0 B/op          0 allocs/op
+
+BenchmarkAce_StaticAll                     30000             49657 ns/op               0 B/op          0 allocs/op
+BenchmarkHttpServeMux_StaticAll             2000           1183737 ns/op              96 B/op          8 allocs/op
+BenchmarkBeego_StaticAll                    5000            412621 ns/op           57776 B/op        628 allocs/op
+BenchmarkBear_StaticAll                    10000            149242 ns/op           20336 B/op        461 allocs/op
+BenchmarkBone_StaticAll                    10000            118583 ns/op               0 B/op          0 allocs/op
+BenchmarkDenco_StaticAll                  100000             13247 ns/op               0 B/op          0 allocs/op
+BenchmarkEcho_StaticAll                    20000             79914 ns/op            5024 B/op        157 allocs/op
+BenchmarkGocraftWeb_StaticAll              10000            211823 ns/op           46440 B/op        785 allocs/op
+BenchmarkGoji_StaticAll                    10000            109390 ns/op               0 B/op          0 allocs/op
+BenchmarkGojiv2_StaticAll                   3000            415533 ns/op          145696 B/op       1099 allocs/op
+BenchmarkGoJsonRest_StaticAll               5000            364403 ns/op           51653 B/op       1727 allocs/op
+BenchmarkGoRestful_StaticAll                 500           2578579 ns/op          314936 B/op       3144 allocs/op
+BenchmarkGorillaMux_StaticAll                500           2704856 ns/op          115648 B/op       1578 allocs/op
+BenchmarkHttpRouter_StaticAll             100000             18541 ns/op               0 B/op          0 allocs/op
+BenchmarkHttpTreeMux_StaticAll            100000             22332 ns/op               0 B/op          0 allocs/op
+BenchmarkKocha_StaticAll                   50000             31176 ns/op               0 B/op          0 allocs/op
+BenchmarkLARS_StaticAll                    50000             40840 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_StaticAll                  5000            517656 ns/op          120576 B/op       1413 allocs/op
+BenchmarkMartini_StaticAll                   300           4462289 ns/op          125442 B/op       1717 allocs/op
+BenchmarkPat_StaticAll                       500           2157275 ns/op          533904 B/op      11123 allocs/op
+BenchmarkPossum_StaticAll                  10000            254701 ns/op           65312 B/op        471 allocs/op
+BenchmarkR2router_StaticAll                10000            133956 ns/op           22608 B/op        628 allocs/op
+BenchmarkRivet_StaticAll                   30000             46812 ns/op               0 B/op          0 allocs/op
+BenchmarkTango_StaticAll                    5000            390613 ns/op           39225 B/op       1256 allocs/op
+BenchmarkTigerTonic_StaticAll              20000             88060 ns/op            7504 B/op        157 allocs/op
+BenchmarkTraffic_StaticAll                   500           2910236 ns/op          729736 B/op      14287 allocs/op
+BenchmarkVulcan_StaticAll                   5000            277366 ns/op           15386 B/op        471 allocs/op
+```
+
+## Micro Benchmarks
+
+```
+BenchmarkGin_Param                      20000000               113 ns/op               0 B/op          0 allocs/op
+
+BenchmarkAce_Param                       5000000               375 ns/op              32 B/op          1 allocs/op
+BenchmarkBear_Param                      1000000              1709 ns/op             456 B/op          5 allocs/op
+BenchmarkBeego_Param                     1000000              2484 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_Param                      1000000              2391 ns/op             688 B/op          5 allocs/op
+BenchmarkDenco_Param                    10000000               240 ns/op              32 B/op          1 allocs/op
+BenchmarkEcho_Param                      5000000               366 ns/op              32 B/op          1 allocs/op
+BenchmarkGocraftWeb_Param                1000000              2343 ns/op             648 B/op          8 allocs/op
+BenchmarkGoji_Param                      1000000              1197 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_Param                    1000000              2771 ns/op             944 B/op          8 allocs/op
+BenchmarkGoJsonRest_Param                1000000              2993 ns/op             649 B/op         13 allocs/op
+BenchmarkGoRestful_Param                  200000              8860 ns/op            2296 B/op         21 allocs/op
+BenchmarkGorillaMux_Param                 500000              4461 ns/op            1056 B/op         11 allocs/op
+BenchmarkHttpRouter_Param               10000000               175 ns/op              32 B/op          1 allocs/op
+BenchmarkHttpTreeMux_Param               1000000              1167 ns/op             352 B/op          3 allocs/op
+BenchmarkKocha_Param                     3000000               429 ns/op              56 B/op          3 allocs/op
+BenchmarkLARS_Param                     10000000               134 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_Param                    500000              4635 ns/op            1056 B/op         10 allocs/op
+BenchmarkMartini_Param                    200000              9933 ns/op            1072 B/op         10 allocs/op
+BenchmarkPat_Param                       1000000              2929 ns/op             648 B/op         12 allocs/op
+BenchmarkPossum_Param                    1000000              2503 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_Param                  1000000              1507 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_Param                     5000000               297 ns/op              48 B/op          1 allocs/op
+BenchmarkTango_Param                     1000000              1862 ns/op             248 B/op          8 allocs/op
+BenchmarkTigerTonic_Param                 500000              5660 ns/op             992 B/op         17 allocs/op
+BenchmarkTraffic_Param                    200000              8408 ns/op            1960 B/op         21 allocs/op
+BenchmarkVulcan_Param                    2000000               963 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_Param5                      2000000               740 ns/op             160 B/op          1 allocs/op
+BenchmarkBear_Param5                     1000000              2777 ns/op             501 B/op          5 allocs/op
+BenchmarkBeego_Param5                    1000000              3740 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_Param5                     1000000              2950 ns/op             736 B/op          5 allocs/op
+BenchmarkDenco_Param5                    2000000               644 ns/op             160 B/op          1 allocs/op
+BenchmarkEcho_Param5                     3000000               558 ns/op              32 B/op          1 allocs/op
+BenchmarkGin_Param5                     10000000               198 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_Param5                500000              3870 ns/op             920 B/op         11 allocs/op
+BenchmarkGoji_Param5                     1000000              1746 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_Param5                   1000000              3214 ns/op            1008 B/op          8 allocs/op
+BenchmarkGoJsonRest_Param5                500000              5509 ns/op            1097 B/op         16 allocs/op
+BenchmarkGoRestful_Param5                 200000             11232 ns/op            2392 B/op         21 allocs/op
+BenchmarkGorillaMux_Param5                300000              7777 ns/op            1184 B/op         11 allocs/op
+BenchmarkHttpRouter_Param5               3000000               631 ns/op             160 B/op          1 allocs/op
+BenchmarkHttpTreeMux_Param5              1000000              2800 ns/op             576 B/op          6 allocs/op
+BenchmarkKocha_Param5                    1000000              2053 ns/op             440 B/op         10 allocs/op
+BenchmarkLARS_Param5                    10000000               232 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_Param5                   500000              5888 ns/op            1056 B/op         10 allocs/op
+BenchmarkMartini_Param5                   200000             12807 ns/op            1232 B/op         11 allocs/op
+BenchmarkPat_Param5                       300000              7320 ns/op             964 B/op         32 allocs/op
+BenchmarkPossum_Param5                   1000000              2495 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_Param5                 1000000              1844 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_Param5                    2000000               935 ns/op             240 B/op          1 allocs/op
+BenchmarkTango_Param5                    1000000              2327 ns/op             360 B/op          8 allocs/op
+BenchmarkTigerTonic_Param5                100000             18514 ns/op            2551 B/op         43 allocs/op
+BenchmarkTraffic_Param5                   200000             11997 ns/op            2248 B/op         25 allocs/op
+BenchmarkVulcan_Param5                   1000000              1333 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_Param20                     1000000              2031 ns/op             640 B/op          1 allocs/op
+BenchmarkBear_Param20                     200000              7285 ns/op            1664 B/op          5 allocs/op
+BenchmarkBeego_Param20                    300000              6224 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_Param20                     200000              8023 ns/op            1903 B/op          5 allocs/op
+BenchmarkDenco_Param20                   1000000              2262 ns/op             640 B/op          1 allocs/op
+BenchmarkEcho_Param20                    1000000              1387 ns/op              32 B/op          1 allocs/op
+BenchmarkGin_Param20                     3000000               503 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_Param20               100000             14408 ns/op            3795 B/op         15 allocs/op
+BenchmarkGoji_Param20                     500000              5272 ns/op            1247 B/op          2 allocs/op
+BenchmarkGojiv2_Param20                  1000000              4163 ns/op            1248 B/op          8 allocs/op
+BenchmarkGoJsonRest_Param20               100000             17866 ns/op            4485 B/op         20 allocs/op
+BenchmarkGoRestful_Param20                100000             21022 ns/op            4724 B/op         23 allocs/op
+BenchmarkGorillaMux_Param20               100000             17055 ns/op            3547 B/op         13 allocs/op
+BenchmarkHttpRouter_Param20              1000000              1748 ns/op             640 B/op          1 allocs/op
+BenchmarkHttpTreeMux_Param20              200000             12246 ns/op            3196 B/op         10 allocs/op
+BenchmarkKocha_Param20                    300000              6861 ns/op            1808 B/op         27 allocs/op
+BenchmarkLARS_Param20                    3000000               526 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_Param20                  100000             13069 ns/op            2906 B/op         12 allocs/op
+BenchmarkMartini_Param20                  100000             23602 ns/op            3597 B/op         13 allocs/op
+BenchmarkPat_Param20                       50000             32143 ns/op            4688 B/op        111 allocs/op
+BenchmarkPossum_Param20                  1000000              2396 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_Param20                 200000              8907 ns/op            2283 B/op          7 allocs/op
+BenchmarkRivet_Param20                   1000000              3280 ns/op            1024 B/op          1 allocs/op
+BenchmarkTango_Param20                    500000              4640 ns/op             856 B/op          8 allocs/op
+BenchmarkTigerTonic_Param20                20000             67581 ns/op           10532 B/op        138 allocs/op
+BenchmarkTraffic_Param20                   50000             40313 ns/op            7941 B/op         45 allocs/op
+BenchmarkVulcan_Param20                  1000000              2264 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_ParamWrite                  3000000               532 ns/op              40 B/op          2 allocs/op
+BenchmarkBear_ParamWrite                 1000000              1778 ns/op             456 B/op          5 allocs/op
+BenchmarkBeego_ParamWrite                1000000              2596 ns/op             376 B/op          5 allocs/op
+BenchmarkBone_ParamWrite                 1000000              2519 ns/op             688 B/op          5 allocs/op
+BenchmarkDenco_ParamWrite                5000000               411 ns/op              32 B/op          1 allocs/op
+BenchmarkEcho_ParamWrite                 2000000               718 ns/op              40 B/op          2 allocs/op
+BenchmarkGin_ParamWrite                  5000000               283 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_ParamWrite           1000000              2561 ns/op             656 B/op          9 allocs/op
+BenchmarkGoji_ParamWrite                 1000000              1378 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_ParamWrite               1000000              3128 ns/op             976 B/op         10 allocs/op
+BenchmarkGoJsonRest_ParamWrite            500000              4446 ns/op            1128 B/op         18 allocs/op
+BenchmarkGoRestful_ParamWrite             200000             10291 ns/op            2304 B/op         22 allocs/op
+BenchmarkGorillaMux_ParamWrite            500000              5153 ns/op            1064 B/op         12 allocs/op
+BenchmarkHttpRouter_ParamWrite           5000000               263 ns/op              32 B/op          1 allocs/op
+BenchmarkHttpTreeMux_ParamWrite          1000000              1351 ns/op             352 B/op          3 allocs/op
+BenchmarkKocha_ParamWrite                3000000               538 ns/op              56 B/op          3 allocs/op
+BenchmarkLARS_ParamWrite                 5000000               316 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_ParamWrite               500000              5756 ns/op            1160 B/op         14 allocs/op
+BenchmarkMartini_ParamWrite               200000             13097 ns/op            1176 B/op         14 allocs/op
+BenchmarkPat_ParamWrite                   500000              4954 ns/op            1072 B/op         17 allocs/op
+BenchmarkPossum_ParamWrite               1000000              2499 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_ParamWrite             1000000              1531 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_ParamWrite                3000000               570 ns/op             112 B/op          2 allocs/op
+BenchmarkTango_ParamWrite                2000000               957 ns/op             136 B/op          4 allocs/op
+BenchmarkTigerTonic_ParamWrite            200000              7025 ns/op            1424 B/op         23 allocs/op
+BenchmarkTraffic_ParamWrite               200000             10112 ns/op            2384 B/op         25 allocs/op
+BenchmarkVulcan_ParamWrite               1000000              1006 ns/op              98 B/op          3 allocs/op
+```
+
+## GitHub
+
+```
+BenchmarkGin_GithubStatic               10000000               156 ns/op               0 B/op          0 allocs/op
+
+BenchmarkAce_GithubStatic                5000000               294 ns/op               0 B/op          0 allocs/op
+BenchmarkBear_GithubStatic               2000000               893 ns/op             120 B/op          3 allocs/op
+BenchmarkBeego_GithubStatic              1000000              2491 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_GithubStatic                 50000             25300 ns/op            2880 B/op         60 allocs/op
+BenchmarkDenco_GithubStatic             20000000                76.0 ns/op             0 B/op          0 allocs/op
+BenchmarkEcho_GithubStatic               2000000               516 ns/op              32 B/op          1 allocs/op
+BenchmarkGocraftWeb_GithubStatic         1000000              1448 ns/op             296 B/op          5 allocs/op
+BenchmarkGoji_GithubStatic               3000000               496 ns/op               0 B/op          0 allocs/op
+BenchmarkGojiv2_GithubStatic             1000000              2941 ns/op             928 B/op          7 allocs/op
+BenchmarkGoRestful_GithubStatic           100000             27256 ns/op            3224 B/op         22 allocs/op
+BenchmarkGoJsonRest_GithubStatic         1000000              2196 ns/op             329 B/op         11 allocs/op
+BenchmarkGorillaMux_GithubStatic           50000             31617 ns/op             736 B/op         10 allocs/op
+BenchmarkHttpRouter_GithubStatic        20000000                88.4 ns/op             0 B/op          0 allocs/op
+BenchmarkHttpTreeMux_GithubStatic       10000000               134 ns/op               0 B/op          0 allocs/op
+BenchmarkKocha_GithubStatic             20000000               113 ns/op               0 B/op          0 allocs/op
+BenchmarkLARS_GithubStatic              10000000               195 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_GithubStatic             500000              3740 ns/op             768 B/op          9 allocs/op
+BenchmarkMartini_GithubStatic              50000             27673 ns/op             768 B/op          9 allocs/op
+BenchmarkPat_GithubStatic                 100000             19470 ns/op            3648 B/op         76 allocs/op
+BenchmarkPossum_GithubStatic             1000000              1729 ns/op             416 B/op          3 allocs/op
+BenchmarkR2router_GithubStatic           2000000               879 ns/op             144 B/op          4 allocs/op
+BenchmarkRivet_GithubStatic             10000000               231 ns/op               0 B/op          0 allocs/op
+BenchmarkTango_GithubStatic              1000000              2325 ns/op             248 B/op          8 allocs/op
+BenchmarkTigerTonic_GithubStatic         3000000               610 ns/op              48 B/op          1 allocs/op
+BenchmarkTraffic_GithubStatic              20000             62973 ns/op           18904 B/op        148 allocs/op
+BenchmarkVulcan_GithubStatic             1000000              1447 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_GithubParam                 2000000               686 ns/op              96 B/op          1 allocs/op
+BenchmarkBear_GithubParam                1000000              2155 ns/op             496 B/op          5 allocs/op
+BenchmarkBeego_GithubParam               1000000              2713 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_GithubParam                 100000             15088 ns/op            1760 B/op         18 allocs/op
+BenchmarkDenco_GithubParam               2000000               629 ns/op             128 B/op          1 allocs/op
+BenchmarkEcho_GithubParam                2000000               653 ns/op              32 B/op          1 allocs/op
+BenchmarkGin_GithubParam                 5000000               255 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_GithubParam          1000000              3145 ns/op             712 B/op          9 allocs/op
+BenchmarkGoji_GithubParam                1000000              1916 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_GithubParam              1000000              3975 ns/op            1024 B/op         10 allocs/op
+BenchmarkGoJsonRest_GithubParam           300000              4134 ns/op             713 B/op         14 allocs/op
+BenchmarkGoRestful_GithubParam             50000             30782 ns/op            2360 B/op         21 allocs/op
+BenchmarkGorillaMux_GithubParam           100000             17148 ns/op            1088 B/op         11 allocs/op
+BenchmarkHttpRouter_GithubParam          3000000               523 ns/op              96 B/op          1 allocs/op
+BenchmarkHttpTreeMux_GithubParam         1000000              1671 ns/op             384 B/op          4 allocs/op
+BenchmarkKocha_GithubParam               1000000              1021 ns/op             128 B/op          5 allocs/op
+BenchmarkLARS_GithubParam                5000000               283 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_GithubParam              500000              4270 ns/op            1056 B/op         10 allocs/op
+BenchmarkMartini_GithubParam              100000             21728 ns/op            1152 B/op         11 allocs/op
+BenchmarkPat_GithubParam                  200000             11208 ns/op            2464 B/op         48 allocs/op
+BenchmarkPossum_GithubParam              1000000              2334 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_GithubParam            1000000              1487 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_GithubParam               2000000               782 ns/op              96 B/op          1 allocs/op
+BenchmarkTango_GithubParam               1000000              2653 ns/op             344 B/op          8 allocs/op
+BenchmarkTigerTonic_GithubParam           300000             14073 ns/op            1440 B/op         24 allocs/op
+BenchmarkTraffic_GithubParam               50000             29164 ns/op            5992 B/op         52 allocs/op
+BenchmarkVulcan_GithubParam              1000000              2529 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_GithubAll                     10000            134059 ns/op           13792 B/op        167 allocs/op
+BenchmarkBear_GithubAll                     5000            534445 ns/op           86448 B/op        943 allocs/op
+BenchmarkBeego_GithubAll                    3000            592444 ns/op           74705 B/op        812 allocs/op
+BenchmarkBone_GithubAll                      200           6957308 ns/op          698784 B/op       8453 allocs/op
+BenchmarkDenco_GithubAll                   10000            158819 ns/op           20224 B/op        167 allocs/op
+BenchmarkEcho_GithubAll                    10000            154700 ns/op            6496 B/op        203 allocs/op
+BenchmarkGin_GithubAll                     30000             48375 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_GithubAll               3000            570806 ns/op          131656 B/op       1686 allocs/op
+BenchmarkGoji_GithubAll                     2000            818034 ns/op           56112 B/op        334 allocs/op
+BenchmarkGojiv2_GithubAll                   2000           1213973 ns/op          274768 B/op       3712 allocs/op
+BenchmarkGoJsonRest_GithubAll               2000            785796 ns/op          134371 B/op       2737 allocs/op
+BenchmarkGoRestful_GithubAll                 300           5238188 ns/op          689672 B/op       4519 allocs/op
+BenchmarkGorillaMux_GithubAll                100          10257726 ns/op          211840 B/op       2272 allocs/op
+BenchmarkHttpRouter_GithubAll              20000            105414 ns/op           13792 B/op        167 allocs/op
+BenchmarkHttpTreeMux_GithubAll             10000            319934 ns/op           65856 B/op        671 allocs/op
+BenchmarkKocha_GithubAll                   10000            209442 ns/op           23304 B/op        843 allocs/op
+BenchmarkLARS_GithubAll                    20000             62565 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_GithubAll                  2000           1161270 ns/op          204194 B/op       2000 allocs/op
+BenchmarkMartini_GithubAll                   200           9991713 ns/op          226549 B/op       2325 allocs/op
+BenchmarkPat_GithubAll                       200           5590793 ns/op         1499568 B/op      27435 allocs/op
+BenchmarkPossum_GithubAll                  10000            319768 ns/op           84448 B/op        609 allocs/op
+BenchmarkR2router_GithubAll                10000            305134 ns/op           77328 B/op        979 allocs/op
+BenchmarkRivet_GithubAll                   10000            132134 ns/op           16272 B/op        167 allocs/op
+BenchmarkTango_GithubAll                    3000            552754 ns/op           63826 B/op       1618 allocs/op
+BenchmarkTigerTonic_GithubAll               1000           1439483 ns/op          239104 B/op       5374 allocs/op
+BenchmarkTraffic_GithubAll                   100          11383067 ns/op         2659329 B/op      21848 allocs/op
+BenchmarkVulcan_GithubAll                   5000            394253 ns/op           19894 B/op        609 allocs/op
+```
+
+## Google+
+
+```
+BenchmarkGin_GPlusStatic                10000000               183 ns/op               0 B/op          0 allocs/op
+
+BenchmarkAce_GPlusStatic                 5000000               276 ns/op               0 B/op          0 allocs/op
+BenchmarkBear_GPlusStatic                2000000               652 ns/op             104 B/op          3 allocs/op
+BenchmarkBeego_GPlusStatic               1000000              2239 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_GPlusStatic                5000000               380 ns/op              32 B/op          1 allocs/op
+BenchmarkDenco_GPlusStatic              30000000                45.8 ns/op             0 B/op          0 allocs/op
+BenchmarkEcho_GPlusStatic                5000000               338 ns/op              32 B/op          1 allocs/op
+BenchmarkGocraftWeb_GPlusStatic          1000000              1158 ns/op             280 B/op          5 allocs/op
+BenchmarkGoji_GPlusStatic                5000000               331 ns/op               0 B/op          0 allocs/op
+BenchmarkGojiv2_GPlusStatic              1000000              2106 ns/op             928 B/op          7 allocs/op
+BenchmarkGoJsonRest_GPlusStatic          1000000              1626 ns/op             329 B/op         11 allocs/op
+BenchmarkGoRestful_GPlusStatic            300000              7598 ns/op            1976 B/op         20 allocs/op
+BenchmarkGorillaMux_GPlusStatic          1000000              2629 ns/op             736 B/op         10 allocs/op
+BenchmarkHttpRouter_GPlusStatic         30000000                52.5 ns/op             0 B/op          0 allocs/op
+BenchmarkHttpTreeMux_GPlusStatic        20000000                85.8 ns/op             0 B/op          0 allocs/op
+BenchmarkKocha_GPlusStatic              20000000                89.2 ns/op             0 B/op          0 allocs/op
+BenchmarkLARS_GPlusStatic               10000000               162 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_GPlusStatic              500000              3479 ns/op             768 B/op          9 allocs/op
+BenchmarkMartini_GPlusStatic              200000              9092 ns/op             768 B/op          9 allocs/op
+BenchmarkPat_GPlusStatic                 3000000               493 ns/op              96 B/op          2 allocs/op
+BenchmarkPossum_GPlusStatic              1000000              1467 ns/op             416 B/op          3 allocs/op
+BenchmarkR2router_GPlusStatic            2000000               788 ns/op             144 B/op          4 allocs/op
+BenchmarkRivet_GPlusStatic              20000000               114 ns/op               0 B/op          0 allocs/op
+BenchmarkTango_GPlusStatic               1000000              1534 ns/op             200 B/op          8 allocs/op
+BenchmarkTigerTonic_GPlusStatic          5000000               282 ns/op              32 B/op          1 allocs/op
+BenchmarkTraffic_GPlusStatic              500000              3798 ns/op            1192 B/op         15 allocs/op
+BenchmarkVulcan_GPlusStatic              2000000              1125 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_GPlusParam                  3000000               528 ns/op              64 B/op          1 allocs/op
+BenchmarkBear_GPlusParam                 1000000              1570 ns/op             480 B/op          5 allocs/op
+BenchmarkBeego_GPlusParam                1000000              2369 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_GPlusParam                 1000000              2028 ns/op             688 B/op          5 allocs/op
+BenchmarkDenco_GPlusParam                5000000               385 ns/op              64 B/op          1 allocs/op
+BenchmarkEcho_GPlusParam                 3000000               441 ns/op              32 B/op          1 allocs/op
+BenchmarkGin_GPlusParam                 10000000               174 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_GPlusParam           1000000              2033 ns/op             648 B/op          8 allocs/op
+BenchmarkGoji_GPlusParam                 1000000              1399 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_GPlusParam               1000000              2641 ns/op             944 B/op          8 allocs/op
+BenchmarkGoJsonRest_GPlusParam           1000000              2824 ns/op             649 B/op         13 allocs/op
+BenchmarkGoRestful_GPlusParam             200000              8875 ns/op            2296 B/op         21 allocs/op
+BenchmarkGorillaMux_GPlusParam            200000              6291 ns/op            1056 B/op         11 allocs/op
+BenchmarkHttpRouter_GPlusParam           5000000               316 ns/op              64 B/op          1 allocs/op
+BenchmarkHttpTreeMux_GPlusParam          1000000              1129 ns/op             352 B/op          3 allocs/op
+BenchmarkKocha_GPlusParam                3000000               538 ns/op              56 B/op          3 allocs/op
+BenchmarkLARS_GPlusParam                10000000               198 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_GPlusParam               500000              3554 ns/op            1056 B/op         10 allocs/op
+BenchmarkMartini_GPlusParam               200000              9831 ns/op            1072 B/op         10 allocs/op
+BenchmarkPat_GPlusParam                  1000000              2706 ns/op             688 B/op         12 allocs/op
+BenchmarkPossum_GPlusParam               1000000              2297 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_GPlusParam             1000000              1318 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_GPlusParam                5000000               399 ns/op              48 B/op          1 allocs/op
+BenchmarkTango_GPlusParam                1000000              2070 ns/op             264 B/op          8 allocs/op
+BenchmarkTigerTonic_GPlusParam            500000              4853 ns/op            1056 B/op         17 allocs/op
+BenchmarkTraffic_GPlusParam               200000              8278 ns/op            1976 B/op         21 allocs/op
+BenchmarkVulcan_GPlusParam               1000000              1243 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_GPlus2Params                3000000               549 ns/op              64 B/op          1 allocs/op
+BenchmarkBear_GPlus2Params               1000000              2112 ns/op             496 B/op          5 allocs/op
+BenchmarkBeego_GPlus2Params               500000              2750 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_GPlus2Params                300000              7032 ns/op            1040 B/op          9 allocs/op
+BenchmarkDenco_GPlus2Params              3000000               502 ns/op              64 B/op          1 allocs/op
+BenchmarkEcho_GPlus2Params               3000000               641 ns/op              32 B/op          1 allocs/op
+BenchmarkGin_GPlus2Params                5000000               250 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_GPlus2Params         1000000              2681 ns/op             712 B/op          9 allocs/op
+BenchmarkGoji_GPlus2Params               1000000              1926 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_GPlus2Params              500000              3996 ns/op            1024 B/op         11 allocs/op
+BenchmarkGoJsonRest_GPlus2Params          500000              3886 ns/op             713 B/op         14 allocs/op
+BenchmarkGoRestful_GPlus2Params           200000             10376 ns/op            2360 B/op         21 allocs/op
+BenchmarkGorillaMux_GPlus2Params          100000             14162 ns/op            1088 B/op         11 allocs/op
+BenchmarkHttpRouter_GPlus2Params         5000000               336 ns/op              64 B/op          1 allocs/op
+BenchmarkHttpTreeMux_GPlus2Params        1000000              1523 ns/op             384 B/op          4 allocs/op
+BenchmarkKocha_GPlus2Params              2000000               970 ns/op             128 B/op          5 allocs/op
+BenchmarkLARS_GPlus2Params               5000000               238 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_GPlus2Params             500000              4016 ns/op            1056 B/op         10 allocs/op
+BenchmarkMartini_GPlus2Params             100000             21253 ns/op            1200 B/op         13 allocs/op
+BenchmarkPat_GPlus2Params                 200000              8632 ns/op            2256 B/op         34 allocs/op
+BenchmarkPossum_GPlus2Params             1000000              2171 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_GPlus2Params           1000000              1340 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_GPlus2Params              3000000               557 ns/op              96 B/op          1 allocs/op
+BenchmarkTango_GPlus2Params              1000000              2186 ns/op             344 B/op          8 allocs/op
+BenchmarkTigerTonic_GPlus2Params          200000              9060 ns/op            1488 B/op         24 allocs/op
+BenchmarkTraffic_GPlus2Params             100000             20324 ns/op            3272 B/op         31 allocs/op
+BenchmarkVulcan_GPlus2Params             1000000              2039 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_GPlusAll                     300000              6603 ns/op             640 B/op         11 allocs/op
+BenchmarkBear_GPlusAll                    100000             22363 ns/op            5488 B/op         61 allocs/op
+BenchmarkBeego_GPlusAll                    50000             38757 ns/op            4784 B/op         52 allocs/op
+BenchmarkBone_GPlusAll                     20000             54916 ns/op           10336 B/op         98 allocs/op
+BenchmarkDenco_GPlusAll                   300000              4959 ns/op             672 B/op         11 allocs/op
+BenchmarkEcho_GPlusAll                    200000              6558 ns/op             416 B/op         13 allocs/op
+BenchmarkGin_GPlusAll                     500000              2757 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_GPlusAll               50000             34615 ns/op            8040 B/op        103 allocs/op
+BenchmarkGoji_GPlusAll                    100000             16002 ns/op            3696 B/op         22 allocs/op
+BenchmarkGojiv2_GPlusAll                   50000             35060 ns/op           12624 B/op        115 allocs/op
+BenchmarkGoJsonRest_GPlusAll               50000             41479 ns/op            8117 B/op        170 allocs/op
+BenchmarkGoRestful_GPlusAll                10000            131653 ns/op           32024 B/op        275 allocs/op
+BenchmarkGorillaMux_GPlusAll               10000            101380 ns/op           13296 B/op        142 allocs/op
+BenchmarkHttpRouter_GPlusAll              500000              3711 ns/op             640 B/op         11 allocs/op
+BenchmarkHttpTreeMux_GPlusAll             100000             14438 ns/op            4032 B/op         38 allocs/op
+BenchmarkKocha_GPlusAll                   200000              8039 ns/op             976 B/op         43 allocs/op
+BenchmarkLARS_GPlusAll                    500000              2630 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_GPlusAll                  30000             51123 ns/op           13152 B/op        128 allocs/op
+BenchmarkMartini_GPlusAll                  10000            176157 ns/op           14016 B/op        145 allocs/op
+BenchmarkPat_GPlusAll                      20000             69911 ns/op           16576 B/op        298 allocs/op
+BenchmarkPossum_GPlusAll                  100000             20716 ns/op            5408 B/op         39 allocs/op
+BenchmarkR2router_GPlusAll                100000             17463 ns/op            5040 B/op         63 allocs/op
+BenchmarkRivet_GPlusAll                   300000              5142 ns/op             768 B/op         11 allocs/op
+BenchmarkTango_GPlusAll                    50000             27321 ns/op            3656 B/op        104 allocs/op
+BenchmarkTigerTonic_GPlusAll               20000             77597 ns/op           14512 B/op        288 allocs/op
+BenchmarkTraffic_GPlusAll                  10000            151406 ns/op           37360 B/op        392 allocs/op
+BenchmarkVulcan_GPlusAll                  100000             18555 ns/op            1274 B/op         39 allocs/op
+```
+
+## Parse.com
+
+```
+BenchmarkGin_ParseStatic                10000000               133 ns/op               0 B/op          0 allocs/op
+
+BenchmarkAce_ParseStatic                 5000000               241 ns/op               0 B/op          0 allocs/op
+BenchmarkBear_ParseStatic                2000000               728 ns/op             120 B/op          3 allocs/op
+BenchmarkBeego_ParseStatic               1000000              2623 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_ParseStatic                1000000              1285 ns/op             144 B/op          3 allocs/op
+BenchmarkDenco_ParseStatic              30000000                57.8 ns/op             0 B/op          0 allocs/op
+BenchmarkEcho_ParseStatic                5000000               342 ns/op              32 B/op          1 allocs/op
+BenchmarkGocraftWeb_ParseStatic          1000000              1478 ns/op             296 B/op          5 allocs/op
+BenchmarkGoji_ParseStatic                3000000               415 ns/op               0 B/op          0 allocs/op
+BenchmarkGojiv2_ParseStatic              1000000              2087 ns/op             928 B/op          7 allocs/op
+BenchmarkGoJsonRest_ParseStatic          1000000              1712 ns/op             329 B/op         11 allocs/op
+BenchmarkGoRestful_ParseStatic            200000             11072 ns/op            3224 B/op         22 allocs/op
+BenchmarkGorillaMux_ParseStatic           500000              4129 ns/op             752 B/op         11 allocs/op
+BenchmarkHttpRouter_ParseStatic         30000000                52.4 ns/op             0 B/op          0 allocs/op
+BenchmarkHttpTreeMux_ParseStatic        20000000               109 ns/op               0 B/op          0 allocs/op
+BenchmarkKocha_ParseStatic              20000000                81.8 ns/op             0 B/op          0 allocs/op
+BenchmarkLARS_ParseStatic               10000000               150 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_ParseStatic             1000000              3288 ns/op             768 B/op          9 allocs/op
+BenchmarkMartini_ParseStatic              200000              9110 ns/op             768 B/op          9 allocs/op
+BenchmarkPat_ParseStatic                 1000000              1135 ns/op             240 B/op          5 allocs/op
+BenchmarkPossum_ParseStatic              1000000              1557 ns/op             416 B/op          3 allocs/op
+BenchmarkR2router_ParseStatic            2000000               730 ns/op             144 B/op          4 allocs/op
+BenchmarkRivet_ParseStatic              10000000               121 ns/op               0 B/op          0 allocs/op
+BenchmarkTango_ParseStatic               1000000              1688 ns/op             248 B/op          8 allocs/op
+BenchmarkTigerTonic_ParseStatic          3000000               427 ns/op              48 B/op          1 allocs/op
+BenchmarkTraffic_ParseStatic              500000              5962 ns/op            1816 B/op         20 allocs/op
+BenchmarkVulcan_ParseStatic              2000000               969 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_ParseParam                  3000000               497 ns/op              64 B/op          1 allocs/op
+BenchmarkBear_ParseParam                 1000000              1473 ns/op             467 B/op          5 allocs/op
+BenchmarkBeego_ParseParam                1000000              2384 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_ParseParam                 1000000              2513 ns/op             768 B/op          6 allocs/op
+BenchmarkDenco_ParseParam                5000000               364 ns/op              64 B/op          1 allocs/op
+BenchmarkEcho_ParseParam                 5000000               418 ns/op              32 B/op          1 allocs/op
+BenchmarkGin_ParseParam                 10000000               163 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_ParseParam           1000000              2361 ns/op             664 B/op          8 allocs/op
+BenchmarkGoji_ParseParam                 1000000              1590 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_ParseParam               1000000              2851 ns/op             976 B/op          9 allocs/op
+BenchmarkGoJsonRest_ParseParam           1000000              2965 ns/op             649 B/op         13 allocs/op
+BenchmarkGoRestful_ParseParam             200000             12207 ns/op            3544 B/op         23 allocs/op
+BenchmarkGorillaMux_ParseParam            500000              5187 ns/op            1088 B/op         12 allocs/op
+BenchmarkHttpRouter_ParseParam           5000000               275 ns/op              64 B/op          1 allocs/op
+BenchmarkHttpTreeMux_ParseParam          1000000              1108 ns/op             352 B/op          3 allocs/op
+BenchmarkKocha_ParseParam                3000000               495 ns/op              56 B/op          3 allocs/op
+BenchmarkLARS_ParseParam                10000000               192 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_ParseParam               500000              4103 ns/op            1056 B/op         10 allocs/op
+BenchmarkMartini_ParseParam               200000              9878 ns/op            1072 B/op         10 allocs/op
+BenchmarkPat_ParseParam                   500000              3657 ns/op            1120 B/op         17 allocs/op
+BenchmarkPossum_ParseParam               1000000              2084 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_ParseParam             1000000              1251 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_ParseParam                5000000               335 ns/op              48 B/op          1 allocs/op
+BenchmarkTango_ParseParam                1000000              1854 ns/op             280 B/op          8 allocs/op
+BenchmarkTigerTonic_ParseParam            500000              4582 ns/op            1008 B/op         17 allocs/op
+BenchmarkTraffic_ParseParam               200000              8125 ns/op            2248 B/op         23 allocs/op
+BenchmarkVulcan_ParseParam               1000000              1148 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_Parse2Params                3000000               539 ns/op              64 B/op          1 allocs/op
+BenchmarkBear_Parse2Params               1000000              1778 ns/op             496 B/op          5 allocs/op
+BenchmarkBeego_Parse2Params              1000000              2519 ns/op             368 B/op          4 allocs/op
+BenchmarkBone_Parse2Params               1000000              2596 ns/op             720 B/op          5 allocs/op
+BenchmarkDenco_Parse2Params              3000000               492 ns/op              64 B/op          1 allocs/op
+BenchmarkEcho_Parse2Params               3000000               484 ns/op              32 B/op          1 allocs/op
+BenchmarkGin_Parse2Params               10000000               193 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_Parse2Params         1000000              2575 ns/op             712 B/op          9 allocs/op
+BenchmarkGoji_Parse2Params               1000000              1373 ns/op             336 B/op          2 allocs/op
+BenchmarkGojiv2_Parse2Params              500000              2416 ns/op             960 B/op          8 allocs/op
+BenchmarkGoJsonRest_Parse2Params          300000              3452 ns/op             713 B/op         14 allocs/op
+BenchmarkGoRestful_Parse2Params           100000             17719 ns/op            6008 B/op         25 allocs/op
+BenchmarkGorillaMux_Parse2Params          300000              5102 ns/op            1088 B/op         11 allocs/op
+BenchmarkHttpRouter_Parse2Params         5000000               303 ns/op              64 B/op          1 allocs/op
+BenchmarkHttpTreeMux_Parse2Params        1000000              1372 ns/op             384 B/op          4 allocs/op
+BenchmarkKocha_Parse2Params              2000000               874 ns/op             128 B/op          5 allocs/op
+BenchmarkLARS_Parse2Params              10000000               192 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_Parse2Params             500000              3871 ns/op            1056 B/op         10 allocs/op
+BenchmarkMartini_Parse2Params             200000              9954 ns/op            1152 B/op         11 allocs/op
+BenchmarkPat_Parse2Params                 500000              4194 ns/op             832 B/op         17 allocs/op
+BenchmarkPossum_Parse2Params             1000000              2121 ns/op             560 B/op          6 allocs/op
+BenchmarkR2router_Parse2Params           1000000              1415 ns/op             432 B/op          5 allocs/op
+BenchmarkRivet_Parse2Params              3000000               457 ns/op              96 B/op          1 allocs/op
+BenchmarkTango_Parse2Params              1000000              1914 ns/op             312 B/op          8 allocs/op
+BenchmarkTigerTonic_Parse2Params          300000              6895 ns/op            1408 B/op         24 allocs/op
+BenchmarkTraffic_Parse2Params             200000              8317 ns/op            2040 B/op         22 allocs/op
+BenchmarkVulcan_Parse2Params             1000000              1274 ns/op              98 B/op          3 allocs/op
+BenchmarkAce_ParseAll                     200000             10401 ns/op             640 B/op         16 allocs/op
+BenchmarkBear_ParseAll                     50000             37743 ns/op            8928 B/op        110 allocs/op
+BenchmarkBeego_ParseAll                    20000             63193 ns/op            9568 B/op        104 allocs/op
+BenchmarkBone_ParseAll                     20000             61767 ns/op           14160 B/op        131 allocs/op
+BenchmarkDenco_ParseAll                   300000              7036 ns/op             928 B/op         16 allocs/op
+BenchmarkEcho_ParseAll                    200000             11824 ns/op             832 B/op         26 allocs/op
+BenchmarkGin_ParseAll                     300000              4199 ns/op               0 B/op          0 allocs/op
+BenchmarkGocraftWeb_ParseAll               30000             51758 ns/op           13728 B/op        181 allocs/op
+BenchmarkGoji_ParseAll                     50000             29614 ns/op            5376 B/op         32 allocs/op
+BenchmarkGojiv2_ParseAll                   20000             68676 ns/op           24464 B/op        199 allocs/op
+BenchmarkGoJsonRest_ParseAll               20000             76135 ns/op           13866 B/op        321 allocs/op
+BenchmarkGoRestful_ParseAll                 5000            389487 ns/op          110928 B/op        600 allocs/op
+BenchmarkGorillaMux_ParseAll               10000            221250 ns/op           24864 B/op        292 allocs/op
+BenchmarkHttpRouter_ParseAll              200000              6444 ns/op             640 B/op         16 allocs/op
+BenchmarkHttpTreeMux_ParseAll              50000             30702 ns/op            5728 B/op         51 allocs/op
+BenchmarkKocha_ParseAll                   200000             13712 ns/op            1112 B/op         54 allocs/op
+BenchmarkLARS_ParseAll                    300000              6925 ns/op               0 B/op          0 allocs/op
+BenchmarkMacaron_ParseAll                  20000             96278 ns/op           24576 B/op        250 allocs/op
+BenchmarkMartini_ParseAll                   5000            271352 ns/op           25072 B/op        253 allocs/op
+BenchmarkPat_ParseAll                      20000             74941 ns/op           17264 B/op        343 allocs/op
+BenchmarkPossum_ParseAll                   50000             39947 ns/op           10816 B/op         78 allocs/op
+BenchmarkR2router_ParseAll                 50000             42479 ns/op            8352 B/op        120 allocs/op
+BenchmarkRivet_ParseAll                   200000              7726 ns/op             912 B/op         16 allocs/op
+BenchmarkTango_ParseAll                    30000             50014 ns/op            7168 B/op        208 allocs/op
+BenchmarkTigerTonic_ParseAll               10000            106550 ns/op           19728 B/op        379 allocs/op
+BenchmarkTraffic_ParseAll                  10000            216037 ns/op           57776 B/op        642 allocs/op
+BenchmarkVulcan_ParseAll                   50000             34379 ns/op            2548 B/op         78 allocs/op
+```
diff --git a/vendor/github.com/gin-gonic/gin/CHANGELOG.md b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
new file mode 100644
index 000000000..e6a108ca3
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
@@ -0,0 +1,213 @@
+# CHANGELOG
+
+### Gin 1.3.0
+
+- [NEW] Add [`func (*Context) QueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.QueryMap), [`func (*Context) GetQueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetQueryMap), [`func (*Context) PostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.PostFormMap) and [`func (*Context) GetPostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetPostFormMap) to support `type map[string]string` as query string or form parameters, see [#1383](https://github.com/gin-gonic/gin/pull/1383)
+- [NEW] Add [`func (*Context) AsciiJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.AsciiJSON), see [#1358](https://github.com/gin-gonic/gin/pull/1358)
+- [NEW] Add `Pusher()` in [`type ResponseWriter`](https://godoc.org/github.com/gin-gonic/gin#ResponseWriter) for supporting http2 push, see [#1273](https://github.com/gin-gonic/gin/pull/1273)
+- [NEW] Add [`func (*Context) DataFromReader`](https://godoc.org/github.com/gin-gonic/gin#Context.DataFromReader) for serving dynamic data, see [#1304](https://github.com/gin-gonic/gin/pull/1304)
+- [NEW] Add [`func (*Context) ShouldBindBodyWith`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindBodyWith) allowing to call binding multiple times, see [#1341](https://github.com/gin-gonic/gin/pull/1341)
+- [NEW] Support pointers in form binding, see [#1336](https://github.com/gin-gonic/gin/pull/1336)
+- [NEW] Add [`func (*Context) JSONP`](https://godoc.org/github.com/gin-gonic/gin#Context.JSONP), see [#1333](https://github.com/gin-gonic/gin/pull/1333)
+- [NEW] Support default value in form binding, see [#1138](https://github.com/gin-gonic/gin/pull/1138)
+- [NEW] Expose validator engine in [`type StructValidator`](https://godoc.org/github.com/gin-gonic/gin/binding#StructValidator), see [#1277](https://github.com/gin-gonic/gin/pull/1277)
+- [NEW] Add [`func (*Context) ShouldBind`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBind), [`func (*Context) ShouldBindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindQuery) and [`func (*Context) ShouldBindJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindJSON), see [#1047](https://github.com/gin-gonic/gin/pull/1047)
+- [NEW] Add support for `time.Time` location in form binding, see [#1117](https://github.com/gin-gonic/gin/pull/1117)
+- [NEW] Add [`func (*Context) BindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.BindQuery), see [#1029](https://github.com/gin-gonic/gin/pull/1029)
+- [NEW] Make [jsonite](https://github.com/json-iterator/go) optional with build tags, see [#1026](https://github.com/gin-gonic/gin/pull/1026)
+- [NEW] Show query string in logger, see [#999](https://github.com/gin-gonic/gin/pull/999)
+- [NEW] Add [`func (*Context) SecureJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.SecureJSON), see [#987](https://github.com/gin-gonic/gin/pull/987) and [#993](https://github.com/gin-gonic/gin/pull/993)
+- [DEPRECATE] `func (*Context) GetCookie` for [`func (*Context) Cookie`](https://godoc.org/github.com/gin-gonic/gin#Context.Cookie)
+- [FIX] Don't display color tags if [`func DisableConsoleColor`](https://godoc.org/github.com/gin-gonic/gin#DisableConsoleColor) called, see [#1072](https://github.com/gin-gonic/gin/pull/1072)
+- [FIX] Gin Mode `""` when calling [`func Mode`](https://godoc.org/github.com/gin-gonic/gin#Mode) now returns `const DebugMode`, see [#1250](https://github.com/gin-gonic/gin/pull/1250)
+- [FIX] `Flush()` now doesn't overwrite `responseWriter` status code, see [#1460](https://github.com/gin-gonic/gin/pull/1460)
+
+### Gin 1.2.0
+
+- [NEW] Switch from godeps to govendor
+- [NEW] Add support for Let's Encrypt via gin-gonic/autotls
+- [NEW] Improve README examples and add extra at examples folder
+- [NEW] Improved support with App Engine
+- [NEW] Add custom template delimiters, see #860
+- [NEW] Add Template Func Maps, see #962
+- [NEW] Add \*context.Handler(), see #928
+- [NEW] Add \*context.GetRawData()
+- [NEW] Add \*context.GetHeader() (request)
+- [NEW] Add \*context.AbortWithStatusJSON() (JSON content type)
+- [NEW] Add \*context.Keys type cast helpers
+- [NEW] Add \*context.ShouldBindWith()
+- [NEW] Add \*context.MustBindWith()
+- [NEW] Add \*engine.SetFuncMap()
+- [DEPRECATE] On next release: \*context.BindWith(), see #855
+- [FIX] Refactor render
+- [FIX] Reworked tests
+- [FIX] logger now supports cygwin
+- [FIX] Use X-Forwarded-For before X-Real-Ip
+- [FIX] time.Time binding (#904)
+
+### Gin 1.1.4
+
+- [NEW] Support google appengine for IsTerminal func
+
+### Gin 1.1.3
+
+- [FIX] Reverted Logger: skip ANSI color commands
+
+### Gin 1.1
+
+- [NEW] Implement QueryArray and PostArray methods 
+- [NEW] Refactor GetQuery and GetPostForm 
+- [NEW] Add contribution guide 
+- [FIX] Corrected typos in README
+- [FIX] Removed additional Iota  
+- [FIX] Changed imports to gopkg instead of github in README (#733) 
+- [FIX] Logger: skip ANSI color commands if output is not a tty
+
+### Gin 1.0rc2 (...)
+
+- [PERFORMANCE] Fast path for writing Content-Type.
+- [PERFORMANCE] Much faster 404 routing
+- [PERFORMANCE] Allocation optimizations
+- [PERFORMANCE] Faster root tree lookup
+- [PERFORMANCE] Zero overhead, String() and JSON() rendering.
+- [PERFORMANCE] Faster ClientIP parsing
+- [PERFORMANCE] Much faster SSE implementation
+- [NEW] Benchmarks suite
+- [NEW] Bind validation can be disabled and replaced with custom validators.
+- [NEW] More flexible HTML render
+- [NEW] Multipart and PostForm bindings
+- [NEW] Adds method to return all the registered routes
+- [NEW] Context.HandlerName() returns the main handler's name
+- [NEW] Adds Error.IsType() helper
+- [FIX] Binding multipart form
+- [FIX] Integration tests
+- [FIX] Crash when binding non struct object in Context.
+- [FIX] RunTLS() implementation
+- [FIX] Logger() unit tests
+- [FIX] Adds SetHTMLTemplate() warning
+- [FIX] Context.IsAborted()
+- [FIX] More unit tests
+- [FIX] JSON, XML, HTML renders accept custom content-types
+- [FIX] gin.AbortIndex is unexported
+- [FIX] Better approach to avoid directory listing in StaticFS()
+- [FIX] Context.ClientIP() always returns the IP with trimmed spaces.
+- [FIX] Better warning when running in debug mode.
+- [FIX] Google App Engine integration. debugPrint does not use os.Stdout
+- [FIX] Fixes integer overflow in error type
+- [FIX] Error implements the json.Marshaller interface
+- [FIX] MIT license in every file
+
+
+### Gin 1.0rc1 (May 22, 2015)
+
+- [PERFORMANCE] Zero allocation router
+- [PERFORMANCE] Faster JSON, XML and text rendering
+- [PERFORMANCE] Custom hand optimized HttpRouter for Gin
+- [PERFORMANCE] Misc code optimizations. Inlining, tail call optimizations
+- [NEW] Built-in support for golang.org/x/net/context
+- [NEW] Any(path, handler). Create a route that matches any path
+- [NEW] Refactored rendering pipeline (faster and static typeded)
+- [NEW] Refactored errors API
+- [NEW] IndentedJSON() prints pretty JSON
+- [NEW] Added gin.DefaultWriter
+- [NEW] UNIX socket support
+- [NEW] RouterGroup.BasePath is exposed
+- [NEW] JSON validation using go-validate-yourself (very powerful options)
+- [NEW] Completed suite of unit tests
+- [NEW] HTTP streaming with c.Stream()
+- [NEW] StaticFile() creates a router for serving just one file.
+- [NEW] StaticFS() has an option to disable directory listing.
+- [NEW] StaticFS() for serving static files through virtual filesystems
+- [NEW] Server-Sent Events native support
+- [NEW] WrapF() and WrapH() helpers for wrapping http.HandlerFunc and http.Handler
+- [NEW] Added LoggerWithWriter() middleware
+- [NEW] Added RecoveryWithWriter() middleware
+- [NEW] Added DefaultPostFormValue()
+- [NEW] Added DefaultFormValue()
+- [NEW] Added DefaultParamValue()
+- [FIX] BasicAuth() when using custom realm
+- [FIX] Bug when serving static files in nested routing group
+- [FIX] Redirect using built-in http.Redirect()
+- [FIX] Logger when printing the requested path
+- [FIX] Documentation typos
+- [FIX] Context.Engine renamed to Context.engine
+- [FIX] Better debugging messages
+- [FIX] ErrorLogger
+- [FIX] Debug HTTP render
+- [FIX] Refactored binding and render modules
+- [FIX] Refactored Context initialization
+- [FIX] Refactored BasicAuth()
+- [FIX] NoMethod/NoRoute handlers
+- [FIX] Hijacking http
+- [FIX] Better support for Google App Engine (using log instead of fmt)
+
+
+### Gin 0.6 (Mar 9, 2015)
+
+- [NEW] Support multipart/form-data
+- [NEW] NoMethod handler
+- [NEW] Validate sub structures
+- [NEW] Support for HTTP Realm Auth
+- [FIX] Unsigned integers in binding
+- [FIX] Improve color logger
+
+
+### Gin 0.5 (Feb 7, 2015)
+
+- [NEW] Content Negotiation
+- [FIX] Solved security bug that allow a client to spoof ip
+- [FIX] Fix unexported/ignored fields in binding
+
+
+### Gin 0.4 (Aug 21, 2014)
+
+- [NEW] Development mode
+- [NEW] Unit tests
+- [NEW] Add Content.Redirect()
+- [FIX] Deferring WriteHeader()
+- [FIX] Improved documentation for model binding
+
+
+### Gin 0.3 (Jul 18, 2014)
+
+- [PERFORMANCE] Normal log and error log are printed in the same call.
+- [PERFORMANCE] Improve performance of NoRouter()
+- [PERFORMANCE] Improve context's memory locality, reduce CPU cache faults.
+- [NEW] Flexible rendering API
+- [NEW] Add Context.File()
+- [NEW] Add shorcut RunTLS() for http.ListenAndServeTLS
+- [FIX] Rename NotFound404() to NoRoute()
+- [FIX] Errors in context are purged
+- [FIX] Adds HEAD method in Static file serving
+- [FIX] Refactors Static() file serving
+- [FIX] Using keyed initialization to fix app-engine integration
+- [FIX] Can't unmarshal JSON array, #63
+- [FIX] Renaming Context.Req to Context.Request
+- [FIX] Check application/x-www-form-urlencoded when parsing form
+
+
+### Gin 0.2b (Jul 08, 2014)
+- [PERFORMANCE] Using sync.Pool to allocatio/gc overhead
+- [NEW] Travis CI integration
+- [NEW] Completely new logger
+- [NEW] New API for serving static files. gin.Static()
+- [NEW] gin.H() can be serialized into XML
+- [NEW] Typed errors. Errors can be typed. Internet/external/custom.
+- [NEW] Support for Godeps
+- [NEW] Travis/Godocs badges in README
+- [NEW] New Bind() and BindWith() methods for parsing request body.
+- [NEW] Add Content.Copy()
+- [NEW] Add context.LastError()
+- [NEW] Add shorcut for OPTIONS HTTP method
+- [FIX] Tons of README fixes
+- [FIX] Header is written before body
+- [FIX] BasicAuth() and changes API a little bit
+- [FIX] Recovery() middleware only prints panics
+- [FIX] Context.Get() does not panic anymore. Use MustGet() instead.
+- [FIX] Multiple http.WriteHeader() in NotFound handlers
+- [FIX] Engine.Run() panics if http server can't be setted up
+- [FIX] Crash when route path doesn't start with '/'
+- [FIX] Do not update header when status code is negative
+- [FIX] Setting response headers before calling WriteHeader in context.String()
+- [FIX] Add MIT license
+- [FIX] Changes behaviour of ErrorLogger() and Logger()
diff --git a/vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md b/vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..4ea14f395
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at teamgingonic@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
new file mode 100644
index 000000000..547b777a1
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
@@ -0,0 +1,13 @@
+## Contributing 
+
+- With issues:
+  - Use the search tool before opening a new issue.
+  - Please provide source code and commit sha if you found a bug.
+  - Review existing issues and provide feedback or react to them.
+
+- With pull requests:
+  - Open your pull request against `master`
+  - Your pull request should have no more than two commits, if not you should squash them.
+  - It should pass all tests in the available continuous integrations systems such as TravisCI.
+  - You should add/modify tests to cover your proposed code changes.
+  - If your pull request contains a new feature, please document it on the README.
diff --git a/vendor/github.com/gin-gonic/gin/Makefile b/vendor/github.com/gin-gonic/gin/Makefile
new file mode 100644
index 000000000..51b9969fd
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/Makefile
@@ -0,0 +1,62 @@
+GOFMT ?= gofmt "-s"
+PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
+VETPACKAGES ?= $(shell go list ./... | grep -v /vendor/ | grep -v /examples/)
+GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
+
+all: install
+
+install: deps
+	govendor sync
+
+.PHONY: test
+test:
+	sh coverage.sh
+
+.PHONY: fmt
+fmt:
+	$(GOFMT) -w $(GOFILES)
+
+.PHONY: fmt-check
+fmt-check:
+	# get all go files and run go fmt on them
+	@diff=$$($(GOFMT) -d $(GOFILES)); \
+	if [ -n "$$diff" ]; then \
+		echo "Please run 'make fmt' and commit the result:"; \
+		echo "$${diff}"; \
+		exit 1; \
+	fi;
+
+vet:
+	go vet $(VETPACKAGES)
+
+deps:
+	@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
+		go get -u github.com/kardianos/govendor; \
+	fi
+	@hash embedmd > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
+		go get -u github.com/campoy/embedmd; \
+	fi
+
+embedmd:
+	embedmd -d *.md
+
+.PHONY: lint
+lint:
+	@hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
+		go get -u github.com/golang/lint/golint; \
+	fi
+	for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
+
+.PHONY: misspell-check
+misspell-check:
+	@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
+		go get -u github.com/client9/misspell/cmd/misspell; \
+	fi
+	misspell -error $(GOFILES)
+
+.PHONY: misspell
+misspell:
+	@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
+		go get -u github.com/client9/misspell/cmd/misspell; \
+	fi
+	misspell -w $(GOFILES)
diff --git a/vendor/github.com/gin-gonic/gin/README.md b/vendor/github.com/gin-gonic/gin/README.md
new file mode 100644
index 000000000..28598baf5
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/README.md
@@ -0,0 +1,1820 @@
+# Gin Web Framework
+
+<img align="right" width="159px" src="https://raw.githubusercontent.com/gin-gonic/logo/master/color.png">
+
+[![Build Status](https://travis-ci.org/gin-gonic/gin.svg)](https://travis-ci.org/gin-gonic/gin)
+[![codecov](https://codecov.io/gh/gin-gonic/gin/branch/master/graph/badge.svg)](https://codecov.io/gh/gin-gonic/gin)
+[![Go Report Card](https://goreportcard.com/badge/github.com/gin-gonic/gin)](https://goreportcard.com/report/github.com/gin-gonic/gin)
+[![GoDoc](https://godoc.org/github.com/gin-gonic/gin?status.svg)](https://godoc.org/github.com/gin-gonic/gin)
+[![Join the chat at https://gitter.im/gin-gonic/gin](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![Sourcegraph](https://sourcegraph.com/github.com/gin-gonic/gin/-/badge.svg)](https://sourcegraph.com/github.com/gin-gonic/gin?badge)
+[![Open Source Helpers](https://www.codetriage.com/gin-gonic/gin/badges/users.svg)](https://www.codetriage.com/gin-gonic/gin)
+
+Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
+
+![Gin console logger](https://gin-gonic.github.io/gin/other/console.png)
+
+## Contents
+
+- [Installation](#installation)
+- [Prerequisite](#prerequisite)
+- [Quick start](#quick-start)
+- [Benchmarks](#benchmarks)
+- [Gin v1.stable](#gin-v1-stable)
+- [Build with jsoniter](#build-with-jsoniter)
+- [API Examples](#api-examples)
+    - [Using GET,POST,PUT,PATCH,DELETE and OPTIONS](#using-get-post-put-patch-delete-and-options)
+    - [Parameters in path](#parameters-in-path)
+    - [Querystring parameters](#querystring-parameters)
+    - [Multipart/Urlencoded Form](#multiparturlencoded-form)
+    - [Another example: query + post form](#another-example-query--post-form)
+    - [Map as querystring or postform parameters](#map-as-querystring-or-postform-parameters)
+    - [Upload files](#upload-files)
+    - [Grouping routes](#grouping-routes)
+    - [Blank Gin without middleware by default](#blank-gin-without-middleware-by-default)
+    - [Using middleware](#using-middleware)
+    - [How to write log file](#how-to-write-log-file)
+    - [Model binding and validation](#model-binding-and-validation)
+    - [Custom Validators](#custom-validators)
+    - [Only Bind Query String](#only-bind-query-string)
+    - [Bind Query String or Post Data](#bind-query-string-or-post-data)
+    - [Bind HTML checkboxes](#bind-html-checkboxes)
+    - [Multipart/Urlencoded binding](#multiparturlencoded-binding)
+    - [XML, JSON and YAML rendering](#xml-json-and-yaml-rendering)
+    - [JSONP rendering](#jsonp)
+    - [Serving static files](#serving-static-files)
+    - [Serving data from reader](#serving-data-from-reader)
+    - [HTML rendering](#html-rendering)
+    - [Multitemplate](#multitemplate)
+    - [Redirects](#redirects)
+    - [Custom Middleware](#custom-middleware)
+    - [Using BasicAuth() middleware](#using-basicauth-middleware)
+    - [Goroutines inside a middleware](#goroutines-inside-a-middleware)
+    - [Custom HTTP configuration](#custom-http-configuration)
+    - [Support Let's Encrypt](#support-lets-encrypt)
+    - [Run multiple service using Gin](#run-multiple-service-using-gin)
+    - [Graceful restart or stop](#graceful-restart-or-stop)
+    - [Build a single binary with templates](#build-a-single-binary-with-templates)
+    - [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct)
+    - [Try to bind body into different structs](#try-to-bind-body-into-different-structs)
+    - [http2 server push](#http2-server-push)
+- [Testing](#testing)
+- [Users](#users--)
+
+## Installation
+
+To install Gin package, you need to install Go and set your Go workspace first.
+
+1. Download and install it:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. Import it in your code:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (Optional) Import `net/http`. This is required for example if using constants such as `http.StatusOK`.
+
+```go
+import "net/http"
+```
+
+### Use a vendor tool like [Govendor](https://github.com/kardianos/govendor)
+
+1. `go get` govendor
+
+```sh
+$ go get github.com/kardianos/govendor
+```
+2. Create your project folder and `cd` inside
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+3. Vendor init your project and add gin
+
+```sh
+$ govendor init
+$ govendor fetch github.com/gin-gonic/gin@v1.2
+```
+
+4. Copy a starting template inside your project
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go > main.go
+```
+
+5. Run your project
+
+```sh
+$ go run main.go
+```
+
+## Prerequisite
+
+Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.
+
+## Quick start
+ 
+```sh
+# assume the following codes in example.go file
+$ cat example.go
+```
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+	r := gin.Default()
+	r.GET("/ping", func(c *gin.Context) {
+		c.JSON(200, gin.H{
+			"message": "pong",
+		})
+	})
+	r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+```
+# run example.go and visit 0.0.0.0:8080/ping on browser
+$ go run example.go
+```
+
+## Benchmarks
+
+Gin uses a custom version of [HttpRouter](https://github.com/julienschmidt/httprouter)
+
+[See all benchmarks](/BENCHMARKS.md)
+
+Benchmark name                              | (1)        | (2)         | (3) 		    | (4)
+--------------------------------------------|-----------:|------------:|-----------:|---------:
+**BenchmarkGin_GithubAll**                  | **30000**  |  **48375**  |     **0**  |   **0**
+BenchmarkAce_GithubAll                      |   10000    |   134059    |   13792    |   167
+BenchmarkBear_GithubAll                     |    5000    |   534445    |   86448    |   943
+BenchmarkBeego_GithubAll                    |    3000    |   592444    |   74705    |   812
+BenchmarkBone_GithubAll                     |     200    |  6957308    |  698784    |  8453
+BenchmarkDenco_GithubAll                    |   10000    |   158819    |   20224    |   167
+BenchmarkEcho_GithubAll                     |   10000    |   154700    |    6496    |   203
+BenchmarkGocraftWeb_GithubAll               |    3000    |   570806    |  131656    |  1686
+BenchmarkGoji_GithubAll                     |    2000    |   818034    |   56112    |   334
+BenchmarkGojiv2_GithubAll                   |    2000    |  1213973    |  274768    |  3712
+BenchmarkGoJsonRest_GithubAll               |    2000    |   785796    |  134371    |  2737
+BenchmarkGoRestful_GithubAll                |     300    |  5238188    |  689672    |  4519
+BenchmarkGorillaMux_GithubAll               |     100    | 10257726    |  211840    |  2272
+BenchmarkHttpRouter_GithubAll               |   20000    |   105414    |   13792    |   167
+BenchmarkHttpTreeMux_GithubAll              |   10000    |   319934    |   65856    |   671
+BenchmarkKocha_GithubAll                    |   10000    |   209442    |   23304    |   843
+BenchmarkLARS_GithubAll                     |   20000    |    62565    |       0    |     0
+BenchmarkMacaron_GithubAll                  |    2000    |  1161270    |  204194    |  2000
+BenchmarkMartini_GithubAll                  |     200    |  9991713    |  226549    |  2325
+BenchmarkPat_GithubAll                      |     200    |  5590793    | 1499568    | 27435
+BenchmarkPossum_GithubAll                   |   10000    |   319768    |   84448    |   609
+BenchmarkR2router_GithubAll                 |   10000    |   305134    |   77328    |   979
+BenchmarkRivet_GithubAll                    |   10000    |   132134    |   16272    |   167
+BenchmarkTango_GithubAll                    |    3000    |   552754    |   63826    |  1618
+BenchmarkTigerTonic_GithubAll               |    1000    |  1439483    |  239104    |  5374
+BenchmarkTraffic_GithubAll                  |     100    | 11383067    | 2659329    | 21848
+BenchmarkVulcan_GithubAll                   |    5000    |   394253    |   19894    |   609
+
+- (1): Total Repetitions achieved in constant time, higher means more confident result
+- (2): Single Repetition Duration (ns/op), lower is better
+- (3): Heap Memory (B/op), lower is better
+- (4): Average Allocations per Repetition (allocs/op), lower is better
+
+## Gin v1. stable
+
+- [x] Zero allocation router.
+- [x] Still the fastest http router and framework. From routing to writing.
+- [x] Complete suite of unit tests
+- [x] Battle tested
+- [x] API frozen, new releases will not break your code.
+
+## Build with [jsoniter](https://github.com/json-iterator/go)
+
+Gin use `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
+
+```sh
+$ go build -tags=jsoniter .
+```
+
+## API Examples
+
+### Using GET, POST, PUT, PATCH, DELETE and OPTIONS
+
+```go
+func main() {
+	// Disable Console Color
+	// gin.DisableConsoleColor()
+
+	// Creates a gin router with default middleware:
+	// logger and recovery (crash-free) middleware
+	router := gin.Default()
+
+	router.GET("/someGet", getting)
+	router.POST("/somePost", posting)
+	router.PUT("/somePut", putting)
+	router.DELETE("/someDelete", deleting)
+	router.PATCH("/somePatch", patching)
+	router.HEAD("/someHead", head)
+	router.OPTIONS("/someOptions", options)
+
+	// By default it serves on :8080 unless a
+	// PORT environment variable was defined.
+	router.Run()
+	// router.Run(":3000") for a hard coded port
+}
+```
+
+### Parameters in path
+
+```go
+func main() {
+	router := gin.Default()
+
+	// This handler will match /user/john but will not match /user/ or /user
+	router.GET("/user/:name", func(c *gin.Context) {
+		name := c.Param("name")
+		c.String(http.StatusOK, "Hello %s", name)
+	})
+
+	// However, this one will match /user/john/ and also /user/john/send
+	// If no other routers match /user/john, it will redirect to /user/john/
+	router.GET("/user/:name/*action", func(c *gin.Context) {
+		name := c.Param("name")
+		action := c.Param("action")
+		message := name + " is " + action
+		c.String(http.StatusOK, message)
+	})
+
+	router.Run(":8080")
+}
+```
+
+### Querystring parameters
+
+```go
+func main() {
+	router := gin.Default()
+
+	// Query string parameters are parsed using the existing underlying request object.
+	// The request responds to a url matching:  /welcome?firstname=Jane&lastname=Doe
+	router.GET("/welcome", func(c *gin.Context) {
+		firstname := c.DefaultQuery("firstname", "Guest")
+		lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
+
+		c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+	})
+	router.Run(":8080")
+}
+```
+
+### Multipart/Urlencoded Form
+
+```go
+func main() {
+	router := gin.Default()
+
+	router.POST("/form_post", func(c *gin.Context) {
+		message := c.PostForm("message")
+		nick := c.DefaultPostForm("nick", "anonymous")
+
+		c.JSON(200, gin.H{
+			"status":  "posted",
+			"message": message,
+			"nick":    nick,
+		})
+	})
+	router.Run(":8080")
+}
+```
+
+### Another example: query + post form
+
+```
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+	router := gin.Default()
+
+	router.POST("/post", func(c *gin.Context) {
+
+		id := c.Query("id")
+		page := c.DefaultQuery("page", "0")
+		name := c.PostForm("name")
+		message := c.PostForm("message")
+
+		fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+	})
+	router.Run(":8080")
+}
+```
+
+```
+id: 1234; page: 1; name: manu; message: this_is_great
+```
+
+### Map as querystring or postform parameters
+
+```
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+	router := gin.Default()
+
+	router.POST("/post", func(c *gin.Context) {
+
+		ids := c.QueryMap("ids")
+		names := c.PostFormMap("names")
+
+		fmt.Printf("ids: %v; names: %v", ids, names)
+	})
+	router.Run(":8080")
+}
+```
+
+```
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
+### Upload files
+
+#### Single file
+
+References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single).
+
+```go
+func main() {
+	router := gin.Default()
+	// Set a lower memory limit for multipart forms (default is 32 MiB)
+	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
+	router.POST("/upload", func(c *gin.Context) {
+		// single file
+		file, _ := c.FormFile("file")
+		log.Println(file.Filename)
+
+		// Upload the file to specific dst.
+		// c.SaveUploadedFile(file, dst)
+
+		c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+	})
+	router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```bash
+curl -X POST http://localhost:8080/upload \
+  -F "file=@/Users/appleboy/test.zip" \
+  -H "Content-Type: multipart/form-data"
+```
+
+#### Multiple files
+
+See the detail [example code](examples/upload-file/multiple).
+
+```go
+func main() {
+	router := gin.Default()
+	// Set a lower memory limit for multipart forms (default is 32 MiB)
+	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
+	router.POST("/upload", func(c *gin.Context) {
+		// Multipart form
+		form, _ := c.MultipartForm()
+		files := form.File["upload[]"]
+
+		for _, file := range files {
+			log.Println(file.Filename)
+
+			// Upload the file to specific dst.
+			// c.SaveUploadedFile(file, dst)
+		}
+		c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+	})
+	router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```bash
+curl -X POST http://localhost:8080/upload \
+  -F "upload[]=@/Users/appleboy/test1.zip" \
+  -F "upload[]=@/Users/appleboy/test2.zip" \
+  -H "Content-Type: multipart/form-data"
+```
+
+### Grouping routes
+
+```go
+func main() {
+	router := gin.Default()
+
+	// Simple group: v1
+	v1 := router.Group("/v1")
+	{
+		v1.POST("/login", loginEndpoint)
+		v1.POST("/submit", submitEndpoint)
+		v1.POST("/read", readEndpoint)
+	}
+
+	// Simple group: v2
+	v2 := router.Group("/v2")
+	{
+		v2.POST("/login", loginEndpoint)
+		v2.POST("/submit", submitEndpoint)
+		v2.POST("/read", readEndpoint)
+	}
+
+	router.Run(":8080")
+}
+```
+
+### Blank Gin without middleware by default
+
+Use
+
+```go
+r := gin.New()
+```
+
+instead of
+
+```go
+// Default With the Logger and Recovery middleware already attached
+r := gin.Default()
+```
+
+
+### Using middleware
+```go
+func main() {
+	// Creates a router without any middleware by default
+	r := gin.New()
+
+	// Global middleware
+	// Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
+	// By default gin.DefaultWriter = os.Stdout
+	r.Use(gin.Logger())
+
+	// Recovery middleware recovers from any panics and writes a 500 if there was one.
+	r.Use(gin.Recovery())
+
+	// Per route middleware, you can add as many as you desire.
+	r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+	// Authorization group
+	// authorized := r.Group("/", AuthRequired())
+	// exactly the same as:
+	authorized := r.Group("/")
+	// per group middleware! in this case we use the custom created
+	// AuthRequired() middleware just in the "authorized" group.
+	authorized.Use(AuthRequired())
+	{
+		authorized.POST("/login", loginEndpoint)
+		authorized.POST("/submit", submitEndpoint)
+		authorized.POST("/read", readEndpoint)
+
+		// nested group
+		testing := authorized.Group("testing")
+		testing.GET("/analytics", analyticsEndpoint)
+	}
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+
+### How to write log file
+```go
+func main() {
+    // Disable Console Color, you don't need console color when writing the logs to file.
+    gin.DisableConsoleColor()
+
+    // Logging to a file.
+    f, _ := os.Create("gin.log")
+    gin.DefaultWriter = io.MultiWriter(f)
+
+    // Use the following code if you need to write the logs to file and console at the same time.
+    // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+    router := gin.Default()
+    router.GET("/ping", func(c *gin.Context) {
+        c.String(200, "pong")
+    })
+
+    router.Run(":8080")
+}
+```
+
+### Model binding and validation
+
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML and standard form values (foo=bar&boo=baz).
+
+Gin uses [**go-playground/validator.v8**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](http://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags).
+
+Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
+
+Also, Gin provides two sets of methods for binding:
+- **Type** - Must bind
+  - **Methods** - `Bind`, `BindJSON`, `BindQuery`
+  - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
+- **Type** - Should bind
+  - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindQuery`
+  - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
+
+When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
+
+You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
+
+```go
+// Binding from JSON
+type Login struct {
+	User     string `form:"user" json:"user" binding:"required"`
+	Password string `form:"password" json:"password" binding:"required"`
+}
+
+func main() {
+	router := gin.Default()
+
+	// Example for binding JSON ({"user": "manu", "password": "123"})
+	router.POST("/loginJSON", func(c *gin.Context) {
+		var json Login
+		if err := c.ShouldBindJSON(&json); err == nil {
+			if json.User == "manu" && json.Password == "123" {
+				c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+			} else {
+				c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+			}
+		} else {
+			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+		}
+	})
+
+	// Example for binding a HTML form (user=manu&password=123)
+	router.POST("/loginForm", func(c *gin.Context) {
+		var form Login
+		// This will infer what binder to use depending on the content-type header.
+		if err := c.ShouldBind(&form); err == nil {
+			if form.User == "manu" && form.Password == "123" {
+				c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+			} else {
+				c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+			}
+		} else {
+			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+		}
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	router.Run(":8080")
+}
+```
+
+**Sample request**
+```shell
+$ curl -v -X POST \
+  http://localhost:8080/loginJSON \
+  -H 'content-type: application/json' \
+  -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+**Skip validate**
+
+When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
+
+### Custom Validators
+
+It is also possible to register custom validators. See the [example code](examples/custom-validation/server.go).
+
+[embedmd]:# (examples/custom-validation/server.go go)
+```go
+package main
+
+import (
+	"net/http"
+	"reflect"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"gopkg.in/go-playground/validator.v8"
+)
+
+type Booking struct {
+	CheckIn  time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+	CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
+}
+
+func bookableDate(
+	v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
+	field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
+) bool {
+	if date, ok := field.Interface().(time.Time); ok {
+		today := time.Now()
+		if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
+			return false
+		}
+	}
+	return true
+}
+
+func main() {
+	route := gin.Default()
+
+	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+		v.RegisterValidation("bookabledate", bookableDate)
+	}
+
+	route.GET("/bookable", getBookable)
+	route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+	var b Booking
+	if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+		c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+	} else {
+		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+	}
+}
+```
+
+```console
+$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
+{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
+```
+
+[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registed this way.
+See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more.
+
+### Only Bind Query String
+
+`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gin-gonic/gin"
+)
+
+type Person struct {
+	Name    string `form:"name"`
+	Address string `form:"address"`
+}
+
+func main() {
+	route := gin.Default()
+	route.Any("/testing", startPage)
+	route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+	var person Person
+	if c.ShouldBindQuery(&person) == nil {
+		log.Println("====== Only Bind By Query String ======")
+		log.Println(person.Name)
+		log.Println(person.Address)
+	}
+	c.String(200, "Success")
+}
+
+```
+
+### Bind Query String or Post Data
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
+
+```go
+package main
+
+import "log"
+import "github.com/gin-gonic/gin"
+import "time"
+
+type Person struct {
+	Name     string    `form:"name"`
+	Address  string    `form:"address"`
+	Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+	route := gin.Default()
+	route.GET("/testing", startPage)
+	route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+	var person Person
+	// If `GET`, only `Form` binding engine (`query`) used.
+	// If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
+	// See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+	if c.ShouldBind(&person) == nil {
+		log.Println(person.Name)
+		log.Println(person.Address)
+		log.Println(person.Birthday)
+	}
+
+	c.String(200, "Success")
+}
+```
+
+Test it with:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
+
+### Bind HTML checkboxes
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+main.go
+
+```go
+...
+
+type myForm struct {
+    Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+    var fakeForm myForm
+    c.ShouldBind(&fakeForm)
+    c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+<form action="/" method="POST">
+    <p>Check some colors</p>
+    <label for="red">Red</label>
+    <input type="checkbox" name="colors[]" value="red" id="red" />
+    <label for="green">Green</label>
+    <input type="checkbox" name="colors[]" value="green" id="green" />
+    <label for="blue">Blue</label>
+    <input type="checkbox" name="colors[]" value="blue" id="blue" />
+    <input type="submit" />
+</form>
+```
+
+result:
+
+```
+{"color":["red","green","blue"]}
+```
+
+### Multipart/Urlencoded binding
+
+```go
+package main
+
+import (
+	"github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+	User     string `form:"user" binding:"required"`
+	Password string `form:"password" binding:"required"`
+}
+
+func main() {
+	router := gin.Default()
+	router.POST("/login", func(c *gin.Context) {
+		// you can bind multipart form with explicit binding declaration:
+		// c.ShouldBindWith(&form, binding.Form)
+		// or you can simply use autobinding with ShouldBind method:
+		var form LoginForm
+		// in this case proper binding will be automatically selected
+		if c.ShouldBind(&form) == nil {
+			if form.User == "user" && form.Password == "password" {
+				c.JSON(200, gin.H{"status": "you are logged in"})
+			} else {
+				c.JSON(401, gin.H{"status": "unauthorized"})
+			}
+		}
+	})
+	router.Run(":8080")
+}
+```
+
+Test it with:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
+
+### XML, JSON and YAML rendering
+
+```go
+func main() {
+	r := gin.Default()
+
+	// gin.H is a shortcut for map[string]interface{}
+	r.GET("/someJSON", func(c *gin.Context) {
+		c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+	})
+
+	r.GET("/moreJSON", func(c *gin.Context) {
+		// You also can use a struct
+		var msg struct {
+			Name    string `json:"user"`
+			Message string
+			Number  int
+		}
+		msg.Name = "Lena"
+		msg.Message = "hey"
+		msg.Number = 123
+		// Note that msg.Name becomes "user" in the JSON
+		// Will output  :   {"user": "Lena", "Message": "hey", "Number": 123}
+		c.JSON(http.StatusOK, msg)
+	})
+
+	r.GET("/someXML", func(c *gin.Context) {
+		c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+	})
+
+	r.GET("/someYAML", func(c *gin.Context) {
+		c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+
+#### SecureJSON
+
+Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
+
+```go
+func main() {
+	r := gin.Default()
+
+	// You can also use your own secure json prefix
+	// r.SecureJsonPrefix(")]}',\n")
+
+	r.GET("/someJSON", func(c *gin.Context) {
+		names := []string{"lena", "austin", "foo"}
+
+		// Will output  :   while(1);["lena","austin","foo"]
+		c.SecureJSON(http.StatusOK, names)
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+#### JSONP
+
+Using JSONP to request data from a server  in a different domain. Add callback to response body if the query parameter callback exists.
+
+```go
+func main() {
+	r := gin.Default()
+
+	r.GET("/JSONP?callback=x", func(c *gin.Context) {
+		data := map[string]interface{}{
+			"foo": "bar",
+		}
+		
+		//callback is x
+		// Will output  :   x({\"foo\":\"bar\"})
+		c.JSONP(http.StatusOK, data)
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+
+#### AsciiJSON
+
+Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII chracters.
+
+```go
+func main() {
+	r := gin.Default()
+
+	r.GET("/someJSON", func(c *gin.Context) {
+		data := map[string]interface{}{
+			"lang": "GO语言",
+			"tag":  "<br>",
+		}
+
+		// will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+		c.AsciiJSON(http.StatusOK, data)
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+
+### Serving static files
+
+```go
+func main() {
+	router := gin.Default()
+	router.Static("/assets", "./assets")
+	router.StaticFS("/more_static", http.Dir("my_file_system"))
+	router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+	// Listen and serve on 0.0.0.0:8080
+	router.Run(":8080")
+}
+```
+
+### Serving data from reader
+
+```go
+func main() {
+	router := gin.Default()
+	router.GET("/someDataFromReader", func(c *gin.Context) {
+		response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+		if err != nil || response.StatusCode != http.StatusOK {
+			c.Status(http.StatusServiceUnavailable)
+			return
+		}
+
+		reader := response.Body
+		contentLength := response.ContentLength
+		contentType := response.Header.Get("Content-Type")
+
+		extraHeaders := map[string]string{
+			"Content-Disposition": `attachment; filename="gopher.png"`,
+		}
+
+		c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+	})
+	router.Run(":8080")
+}
+```
+
+### HTML rendering
+
+Using LoadHTMLGlob() or LoadHTMLFiles()
+
+```go
+func main() {
+	router := gin.Default()
+	router.LoadHTMLGlob("templates/*")
+	//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+	router.GET("/index", func(c *gin.Context) {
+		c.HTML(http.StatusOK, "index.tmpl", gin.H{
+			"title": "Main website",
+		})
+	})
+	router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+<html>
+	<h1>
+		{{ .title }}
+	</h1>
+</html>
+```
+
+Using templates with same name in different directories
+
+```go
+func main() {
+	router := gin.Default()
+	router.LoadHTMLGlob("templates/**/*")
+	router.GET("/posts/index", func(c *gin.Context) {
+		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+			"title": "Posts",
+		})
+	})
+	router.GET("/users/index", func(c *gin.Context) {
+		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+			"title": "Users",
+		})
+	})
+	router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+<html><h1>
+	{{ .title }}
+</h1>
+<p>Using posts/index.tmpl</p>
+</html>
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+<html><h1>
+	{{ .title }}
+</h1>
+<p>Using users/index.tmpl</p>
+</html>
+{{ end }}
+```
+
+#### Custom Template renderer
+
+You can also use your own html template render
+
+```go
+import "html/template"
+
+func main() {
+	router := gin.Default()
+	html := template.Must(template.ParseFiles("file1", "file2"))
+	router.SetHTMLTemplate(html)
+	router.Run(":8080")
+}
+```
+
+#### Custom Delimiters
+
+You may use custom delims
+
+```go
+	r := gin.Default()
+	r.Delims("{[{", "}]}")
+	r.LoadHTMLGlob("/path/to/templates"))
+```
+
+#### Custom Template Funcs
+
+See the detail [example code](examples/template).
+
+main.go
+
+```go
+import (
+    "fmt"
+    "html/template"
+    "net/http"
+    "time"
+
+    "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+    year, month, day := t.Date()
+    return fmt.Sprintf("%d%02d/%02d", year, month, day)
+}
+
+func main() {
+    router := gin.Default()
+    router.Delims("{[{", "}]}")
+    router.SetFuncMap(template.FuncMap{
+        "formatAsDate": formatAsDate,
+    })
+    router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+    router.GET("/raw", func(c *gin.Context) {
+        c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+            "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+        })
+    })
+
+    router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```html
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```
+Date: 2017/07/01
+```
+
+### Multitemplate
+
+Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
+
+### Redirects
+
+Issuing a HTTP redirect is easy. Both internal and external locations are supported.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+	c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+
+Issuing a Router redirect, use `HandleContext` like below.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+    c.Request.URL.Path = "/test2"
+    r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+    c.JSON(200, gin.H{"hello": "world"})
+})
+```
+
+
+### Custom Middleware
+
+```go
+func Logger() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		t := time.Now()
+
+		// Set example variable
+		c.Set("example", "12345")
+
+		// before request
+
+		c.Next()
+
+		// after request
+		latency := time.Since(t)
+		log.Print(latency)
+
+		// access the status we are sending
+		status := c.Writer.Status()
+		log.Println(status)
+	}
+}
+
+func main() {
+	r := gin.New()
+	r.Use(Logger())
+
+	r.GET("/test", func(c *gin.Context) {
+		example := c.MustGet("example").(string)
+
+		// it would print: "12345"
+		log.Println(example)
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+
+### Using BasicAuth() middleware
+
+```go
+// simulate some private data
+var secrets = gin.H{
+	"foo":    gin.H{"email": "foo@bar.com", "phone": "123433"},
+	"austin": gin.H{"email": "austin@example.com", "phone": "666"},
+	"lena":   gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+	r := gin.Default()
+
+	// Group using gin.BasicAuth() middleware
+	// gin.Accounts is a shortcut for map[string]string
+	authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+		"foo":    "bar",
+		"austin": "1234",
+		"lena":   "hello2",
+		"manu":   "4321",
+	}))
+
+	// /admin/secrets endpoint
+	// hit "localhost:8080/admin/secrets
+	authorized.GET("/secrets", func(c *gin.Context) {
+		// get user, it was set by the BasicAuth middleware
+		user := c.MustGet(gin.AuthUserKey).(string)
+		if secret, ok := secrets[user]; ok {
+			c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+		} else {
+			c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+		}
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+
+### Goroutines inside a middleware
+
+When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
+
+```go
+func main() {
+	r := gin.Default()
+
+	r.GET("/long_async", func(c *gin.Context) {
+		// create copy to be used inside the goroutine
+		cCp := c.Copy()
+		go func() {
+			// simulate a long task with time.Sleep(). 5 seconds
+			time.Sleep(5 * time.Second)
+
+			// note that you are using the copied context "cCp", IMPORTANT
+			log.Println("Done! in path " + cCp.Request.URL.Path)
+		}()
+	})
+
+	r.GET("/long_sync", func(c *gin.Context) {
+		// simulate a long task with time.Sleep(). 5 seconds
+		time.Sleep(5 * time.Second)
+
+		// since we are NOT using a goroutine, we do not have to copy the context
+		log.Println("Done! in path " + c.Request.URL.Path)
+	})
+
+	// Listen and serve on 0.0.0.0:8080
+	r.Run(":8080")
+}
+```
+
+### Custom HTTP configuration
+
+Use `http.ListenAndServe()` directly, like this:
+
+```go
+func main() {
+	router := gin.Default()
+	http.ListenAndServe(":8080", router)
+}
+```
+or
+
+```go
+func main() {
+	router := gin.Default()
+
+	s := &http.Server{
+		Addr:           ":8080",
+		Handler:        router,
+		ReadTimeout:    10 * time.Second,
+		WriteTimeout:   10 * time.Second,
+		MaxHeaderBytes: 1 << 20,
+	}
+	s.ListenAndServe()
+}
+```
+
+### Support Let's Encrypt
+
+example for 1-line LetsEncrypt HTTPS servers.
+
+[embedmd]:# (examples/auto-tls/example1/main.go go)
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gin-gonic/autotls"
+	"github.com/gin-gonic/gin"
+)
+
+func main() {
+	r := gin.Default()
+
+	// Ping handler
+	r.GET("/ping", func(c *gin.Context) {
+		c.String(200, "pong")
+	})
+
+	log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+example for custom autocert manager.
+
+[embedmd]:# (examples/auto-tls/example2/main.go go)
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gin-gonic/autotls"
+	"github.com/gin-gonic/gin"
+	"golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+	r := gin.Default()
+
+	// Ping handler
+	r.GET("/ping", func(c *gin.Context) {
+		c.String(200, "pong")
+	})
+
+	m := autocert.Manager{
+		Prompt:     autocert.AcceptTOS,
+		HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+		Cache:      autocert.DirCache("/var/www/.cache"),
+	}
+
+	log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
+### Run multiple service using Gin
+
+See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
+
+[embedmd]:# (examples/multiple-service/main.go go)
+```go
+package main
+
+import (
+	"log"
+	"net/http"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	"golang.org/x/sync/errgroup"
+)
+
+var (
+	g errgroup.Group
+)
+
+func router01() http.Handler {
+	e := gin.New()
+	e.Use(gin.Recovery())
+	e.GET("/", func(c *gin.Context) {
+		c.JSON(
+			http.StatusOK,
+			gin.H{
+				"code":  http.StatusOK,
+				"error": "Welcome server 01",
+			},
+		)
+	})
+
+	return e
+}
+
+func router02() http.Handler {
+	e := gin.New()
+	e.Use(gin.Recovery())
+	e.GET("/", func(c *gin.Context) {
+		c.JSON(
+			http.StatusOK,
+			gin.H{
+				"code":  http.StatusOK,
+				"error": "Welcome server 02",
+			},
+		)
+	})
+
+	return e
+}
+
+func main() {
+	server01 := &http.Server{
+		Addr:         ":8080",
+		Handler:      router01(),
+		ReadTimeout:  5 * time.Second,
+		WriteTimeout: 10 * time.Second,
+	}
+
+	server02 := &http.Server{
+		Addr:         ":8081",
+		Handler:      router02(),
+		ReadTimeout:  5 * time.Second,
+		WriteTimeout: 10 * time.Second,
+	}
+
+	g.Go(func() error {
+		return server01.ListenAndServe()
+	})
+
+	g.Go(func() error {
+		return server02.ListenAndServe()
+	})
+
+	if err := g.Wait(); err != nil {
+		log.Fatal(err)
+	}
+}
+```
+
+### Graceful restart or stop
+
+Do you want to graceful restart or stop your web server?
+There are some ways this can be done.
+
+We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+An alternative to endless:
+
+* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
+* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
+
+If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](./examples/graceful-shutdown) example with gin.
+
+[embedmd]:# (examples/graceful-shutdown/graceful-shutdown/server.go go)
+```go
+// +build go1.8
+
+package main
+
+import (
+	"context"
+	"log"
+	"net/http"
+	"os"
+	"os/signal"
+	"time"
+
+	"github.com/gin-gonic/gin"
+)
+
+func main() {
+	router := gin.Default()
+	router.GET("/", func(c *gin.Context) {
+		time.Sleep(5 * time.Second)
+		c.String(http.StatusOK, "Welcome Gin Server")
+	})
+
+	srv := &http.Server{
+		Addr:    ":8080",
+		Handler: router,
+	}
+
+	go func() {
+		// service connections
+		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+			log.Fatalf("listen: %s\n", err)
+		}
+	}()
+
+	// Wait for interrupt signal to gracefully shutdown the server with
+	// a timeout of 5 seconds.
+	quit := make(chan os.Signal)
+	signal.Notify(quit, os.Interrupt)
+	<-quit
+	log.Println("Shutdown Server ...")
+
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	if err := srv.Shutdown(ctx); err != nil {
+		log.Fatal("Server Shutdown:", err)
+	}
+	log.Println("Server exiting")
+}
+```
+
+### Build a single binary with templates
+
+You can build a server into a single binary containing templates by using [go-assets][].
+
+[go-assets]: https://github.com/jessevdk/go-assets
+
+```go
+func main() {
+	r := gin.New()
+
+	t, err := loadTemplate()
+	if err != nil {
+		panic(err)
+	}
+	r.SetHTMLTemplate(t)
+
+	r.GET("/", func(c *gin.Context) {
+		c.HTML(http.StatusOK, "/html/index.tmpl",nil)
+	})
+	r.Run(":8080")
+}
+
+// loadTemplate loads templates embedded by go-assets-builder
+func loadTemplate() (*template.Template, error) {
+	t := template.New("")
+	for name, file := range Assets.Files {
+		if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+			continue
+		}
+		h, err := ioutil.ReadAll(file)
+		if err != nil {
+			return nil, err
+		}
+		t, err = t.New(name).Parse(string(h))
+		if err != nil {
+			return nil, err
+		}
+	}
+	return t, nil
+}
+```
+
+See a complete example in the `examples/assets-in-binary` directory.
+
+### Bind form-data request with custom struct
+
+The follow example using custom struct:
+
+```go
+type StructA struct {
+    FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+    NestedStruct StructA
+    FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+    NestedStructPointer *StructA
+    FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+    NestedAnonyStruct struct {
+        FieldX string `form:"field_x"`
+    }
+    FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+    var b StructB
+    c.Bind(&b)
+    c.JSON(200, gin.H{
+        "a": b.NestedStruct,
+        "b": b.FieldB,
+    })
+}
+
+func GetDataC(c *gin.Context) {
+    var b StructC
+    c.Bind(&b)
+    c.JSON(200, gin.H{
+        "a": b.NestedStructPointer,
+        "c": b.FieldC,
+    })
+}
+
+func GetDataD(c *gin.Context) {
+    var b StructD
+    c.Bind(&b)
+    c.JSON(200, gin.H{
+        "x": b.NestedAnonyStruct,
+        "d": b.FieldD,
+    })
+}
+
+func main() {
+    r := gin.Default()
+    r.GET("/getb", GetDataB)
+    r.GET("/getc", GetDataC)
+    r.GET("/getd", GetDataD)
+
+    r.Run()
+}
+```
+
+Using the command `curl` command result:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
+**NOTE**: NOT support the follow style struct:
+
+```go
+type StructX struct {
+    X struct {} `form:"name_x"` // HERE have form
+}
+
+type StructY struct {
+    Y StructX `form:"name_y"` // HERE hava form
+}
+
+type StructZ struct {
+    Z *StructZ `form:"name_z"` // HERE hava form
+}
+```
+
+In a word, only support nested custom struct which have no `form` now.
+
+### Try to bind body into different structs
+
+The normal methods for binding request body consumes `c.Request.Body` and they
+cannot be called multiple times.
+
+```go
+type formA struct {
+  Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+  Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+  objA := formA{}
+  objB := formB{}
+  // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
+  if errA := c.ShouldBind(&objA); errA == nil {
+    c.String(http.StatusOK, `the body should be formA`)
+  // Always an error is occurred by this because c.Request.Body is EOF now.
+  } else if errB := c.ShouldBind(&objB); errB == nil {
+    c.String(http.StatusOK, `the body should be formB`)
+  } else {
+    ...
+  }
+}
+```
+
+For this, you can use `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+  objA := formA{}
+  objB := formB{}
+  // This reads c.Request.Body and stores the result into the context.
+  if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+    c.String(http.StatusOK, `the body should be formA`)
+  // At this time, it reuses body stored in the context.
+  } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+    c.String(http.StatusOK, `the body should be formB JSON`)
+  // And it can accepts other formats
+  } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+    c.String(http.StatusOK, `the body should be formB XML`)
+  } else {
+    ...
+  }
+}
+```
+
+* `c.ShouldBindBodyWith` stores body into the context before binding. This has
+a slight impact to performance, so you should not use this method if you are
+enough to call binding at once.
+* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
+can be called by `c.ShouldBind()` multiple times without any damage to
+performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
+### http2 server push
+
+http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
+
+[embedmd]:# (examples/http-pusher/main.go go)
+```go
+package main
+
+import (
+	"html/template"
+	"log"
+
+	"github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+<html>
+<head>
+  <title>Https Test</title>
+  <script src="/assets/app.js"></script>
+</head>
+<body>
+  <h1 style="color:red;">Welcome, Ginner!</h1>
+</body>
+</html>
+`))
+
+func main() {
+	r := gin.Default()
+	r.Static("/assets", "./assets")
+	r.SetHTMLTemplate(html)
+
+	r.GET("/", func(c *gin.Context) {
+		if pusher := c.Writer.Pusher(); pusher != nil {
+			// use pusher.Push() to do server push
+			if err := pusher.Push("/assets/app.js", nil); err != nil {
+				log.Printf("Failed to push: %v", err)
+			}
+		}
+		c.HTML(200, "https", gin.H{
+			"status": "success",
+		})
+	})
+
+	// Listen and Server in https://127.0.0.1:8080
+	r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
+## Testing
+
+The `net/http/httptest` package is preferable way for HTTP testing.
+
+```go
+package main
+
+func setupRouter() *gin.Engine {
+	r := gin.Default()
+	r.GET("/ping", func(c *gin.Context) {
+		c.String(200, "pong")
+	})
+	return r
+}
+
+func main() {
+	r := setupRouter()
+	r.Run(":8080")
+}
+```
+
+Test for code example above:
+
+```go
+package main
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+	router := setupRouter()
+
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("GET", "/ping", nil)
+	router.ServeHTTP(w, req)
+
+	assert.Equal(t, 200, w.Code)
+	assert.Equal(t, "pong", w.Body.String())
+}
+```
+
+## Users
+
+Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework.
+
+* [drone](https://github.com/drone/drone): Drone is a Continuous Delivery platform built on Docker, written in Go
+* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
diff --git a/vendor/github.com/gin-gonic/gin/codecov.yml b/vendor/github.com/gin-gonic/gin/codecov.yml
new file mode 100644
index 000000000..c9c9a522d
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/codecov.yml
@@ -0,0 +1,5 @@
+coverage:
+  notify:
+    gitter:
+      default:
+        url: https://webhooks.gitter.im/e/d90dcdeeab2f1e357165
diff --git a/vendor/github.com/gin-gonic/gin/coverage.sh b/vendor/github.com/gin-gonic/gin/coverage.sh
new file mode 100644
index 000000000..4d1ee0361
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/coverage.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+set -e
+
+echo "mode: count" > coverage.out
+
+for d in $(go list ./... | grep -E 'gin$|binding$|render$' | grep -v 'examples'); do
+    go test -v -covermode=count -coverprofile=profile.out $d
+    if [ -f profile.out ]; then
+        cat profile.out | grep -v "mode:" >> coverage.out
+        rm profile.out
+    fi
+done
diff --git a/vendor/github.com/gin-gonic/gin/wercker.yml b/vendor/github.com/gin-gonic/gin/wercker.yml
new file mode 100644
index 000000000..3ab8084cc
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/wercker.yml
@@ -0,0 +1 @@
+box: wercker/default
\ No newline at end of file
diff --git a/vendor/github.com/go-ini/ini/.gitignore b/vendor/github.com/go-ini/ini/.gitignore
new file mode 100644
index 000000000..12411127b
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/.gitignore
@@ -0,0 +1,6 @@
+testdata/conf_out.ini
+ini.sublime-project
+ini.sublime-workspace
+testdata/conf_reflect.ini
+.idea
+/.vscode
diff --git a/vendor/github.com/go-ini/ini/.travis.yml b/vendor/github.com/go-ini/ini/.travis.yml
new file mode 100644
index 000000000..c8ea49ccc
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/.travis.yml
@@ -0,0 +1,17 @@
+sudo: false
+language: go
+go:
+  - 1.6.x
+  - 1.7.x
+  - 1.8.x
+  - 1.9.x
+  - 1.10.x
+  - 1.11.x
+
+script:
+  - go get golang.org/x/tools/cmd/cover
+  - go get github.com/smartystreets/goconvey
+  - mkdir -p $HOME/gopath/src/gopkg.in
+  - ln -s $HOME/gopath/src/github.com/go-ini/ini $HOME/gopath/src/gopkg.in/ini.v1
+  - cd $HOME/gopath/src/gopkg.in/ini.v1
+  - go test -v -cover -race
diff --git a/vendor/github.com/go-ini/ini/Makefile b/vendor/github.com/go-ini/ini/Makefile
new file mode 100644
index 000000000..af27ff076
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/Makefile
@@ -0,0 +1,15 @@
+.PHONY: build test bench vet coverage
+
+build: vet bench
+
+test:
+	go test -v -cover -race
+
+bench:
+	go test -v -cover -race -test.bench=. -test.benchmem
+
+vet:
+	go vet
+
+coverage:
+	go test -coverprofile=c.out && go tool cover -html=c.out && rm c.out
diff --git a/vendor/github.com/go-ini/ini/README.md b/vendor/github.com/go-ini/ini/README.md
new file mode 100644
index 000000000..ae4dfc3a5
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/README.md
@@ -0,0 +1,46 @@
+INI [![Build Status](https://travis-ci.org/go-ini/ini.svg?branch=master)](https://travis-ci.org/go-ini/ini) [![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg)](https://sourcegraph.com/github.com/go-ini/ini)
+===
+
+![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200)
+
+Package ini provides INI file read and write functionality in Go.
+
+## Features
+
+- Load from multiple data sources(`[]byte`, file and `io.ReadCloser`) with overwrites.
+- Read with recursion values.
+- Read with parent-child sections.
+- Read with auto-increment key names.
+- Read with multiple-line values.
+- Read with tons of helper methods.
+- Read and convert values to Go types.
+- Read and **WRITE** comments of sections and keys.
+- Manipulate sections, keys and comments with ease.
+- Keep sections and keys in order as you parse and save.
+
+## Installation
+
+The minimum requirement of Go is **1.6**.
+
+To use a tagged revision:
+
+```sh
+$ go get gopkg.in/ini.v1
+```
+
+To use with latest changes:
+
+```sh
+$ go get github.com/go-ini/ini
+```
+
+Please add `-u` flag to update in the future.
+
+## Getting Help
+
+- [Getting Started](https://ini.unknwon.io/docs/intro/getting_started)
+- [API Documentation](https://gowalker.org/gopkg.in/ini.v1)
+
+## License
+
+This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.
diff --git a/vendor/github.com/go-ole/go-ole/.travis.yml b/vendor/github.com/go-ole/go-ole/.travis.yml
new file mode 100644
index 000000000..0c2c02bdf
--- /dev/null
+++ b/vendor/github.com/go-ole/go-ole/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+sudo: false
+
+go:
+  - 1.1
+  - 1.2
+  - 1.3
+  - 1.4
+  - tip
diff --git a/vendor/github.com/go-ole/go-ole/ChangeLog.md b/vendor/github.com/go-ole/go-ole/ChangeLog.md
new file mode 100644
index 000000000..4ba6a8c64
--- /dev/null
+++ b/vendor/github.com/go-ole/go-ole/ChangeLog.md
@@ -0,0 +1,49 @@
+# Version 1.x.x
+
+* **Add more test cases and reference new test COM server project.** (Placeholder for future additions)
+
+# Version 1.2.0-alphaX
+
+**Minimum supported version is now Go 1.4. Go 1.1 support is deprecated, but should still build.**
+
+ * Added CI configuration for Travis-CI and AppVeyor.
+ * Added test InterfaceID and ClassID for the COM Test Server project.
+ * Added more inline documentation (#83).
+ * Added IEnumVARIANT implementation (#88).
+ * Added IEnumVARIANT test cases (#99, #100, #101).
+ * Added support for retrieving `time.Time` from VARIANT (#92).
+ * Added test case for IUnknown (#64).
+ * Added test case for IDispatch (#64).
+ * Added test cases for scalar variants (#64, #76).
+
+# Version 1.1.1
+
+ * Fixes for Linux build.
+ * Fixes for Windows build.
+
+# Version 1.1.0
+
+The change to provide building on all platforms is a new feature. The increase in minor version reflects that and allows those who wish to stay on 1.0.x to continue to do so. Support for 1.0.x will be limited to bug fixes.
+
+ * Move GUID out of variables.go into its own file to make new documentation available.
+ * Move OleError out of ole.go into its own file to make new documentation available.
+ * Add documentation to utility functions.
+ * Add documentation to variant receiver functions.
+ * Add documentation to ole structures.
+ * Make variant available to other systems outside of Windows.
+ * Make OLE structures available to other systems outside of Windows.
+
+## New Features
+
+ * Library should now be built on all platforms supported by Go. Library will NOOP on any platform that is not Windows.
+ * More functions are now documented and available on godoc.org.
+
+# Version 1.0.1
+
+ 1. Fix package references from repository location change.
+
+# Version 1.0.0
+
+This version is stable enough for use. The COM API is still incomplete, but provides enough functionality for accessing COM servers using IDispatch interface.
+
+There is no changelog for this version. Check commits for history.
diff --git a/vendor/github.com/go-ole/go-ole/README.md b/vendor/github.com/go-ole/go-ole/README.md
new file mode 100644
index 000000000..0ea9db33c
--- /dev/null
+++ b/vendor/github.com/go-ole/go-ole/README.md
@@ -0,0 +1,46 @@
+#Go OLE
+
+[![Build status](https://ci.appveyor.com/api/projects/status/qr0u2sf7q43us9fj?svg=true)](https://ci.appveyor.com/project/jacobsantos/go-ole-jgs28)
+[![Build Status](https://travis-ci.org/go-ole/go-ole.svg?branch=master)](https://travis-ci.org/go-ole/go-ole)
+[![GoDoc](https://godoc.org/github.com/go-ole/go-ole?status.svg)](https://godoc.org/github.com/go-ole/go-ole)
+
+Go bindings for Windows COM using shared libraries instead of cgo.
+
+By Yasuhiro Matsumoto.
+
+## Install
+
+To experiment with go-ole, you can just compile and run the example program:
+
+```
+go get github.com/go-ole/go-ole
+cd /path/to/go-ole/
+go test
+
+cd /path/to/go-ole/example/excel
+go run excel.go
+```
+
+## Continuous Integration
+
+Continuous integration configuration has been added for both Travis-CI and AppVeyor. You will have to add these to your own account for your fork in order for it to run.
+
+**Travis-CI**
+
+Travis-CI was added to check builds on Linux to ensure that `go get` works when cross building. Currently, Travis-CI is not used to test cross-building, but this may be changed in the future. It is also not currently possible to test the library on Linux, since COM API is specific to Windows and it is not currently possible to run a COM server on Linux or even connect to a remote COM server.
+
+**AppVeyor**
+
+AppVeyor is used to build on Windows using the (in-development) test COM server. It is currently only used to test the build and ensure that the code works on Windows. It will be used to register a COM server and then run the test cases based on the test COM server.
+
+The tests currently do run and do pass and this should be maintained with commits.
+
+##Versioning
+
+Go OLE uses [semantic versioning](http://semver.org) for version numbers, which is similar to the version contract of the Go language. Which means that the major version will always maintain backwards compatibility with minor versions. Minor versions will only add new additions and changes. Fixes will always be in patch. 
+
+This contract should allow you to upgrade to new minor and patch versions without breakage or modifications to your existing code. Leave a ticket, if there is breakage, so that it could be fixed.
+
+##LICENSE
+
+Under the MIT License: http://mattn.mit-license.org/2013
diff --git a/vendor/github.com/go-ole/go-ole/appveyor.yml b/vendor/github.com/go-ole/go-ole/appveyor.yml
new file mode 100644
index 000000000..0d557ac2f
--- /dev/null
+++ b/vendor/github.com/go-ole/go-ole/appveyor.yml
@@ -0,0 +1,54 @@
+# Notes:
+#   - Minimal appveyor.yml file is an empty file. All sections are optional.
+#   - Indent each level of configuration with 2 spaces. Do not use tabs!
+#   - All section names are case-sensitive.
+#   - Section names should be unique on each level.
+
+version: "1.3.0.{build}-alpha-{branch}"
+
+os: Windows Server 2012 R2
+
+branches:
+  only:
+    - master
+    - v1.2
+    - v1.1
+    - v1.0
+
+skip_tags: true
+
+clone_folder: c:\gopath\src\github.com\go-ole\go-ole
+
+environment:
+  GOPATH: c:\gopath
+  matrix:
+  - GOARCH: amd64
+    GOVERSION: 1.5
+    GOROOT: c:\go
+    DOWNLOADPLATFORM: "x64"
+
+install:
+  - choco install mingw
+  - SET PATH=c:\tools\mingw64\bin;%PATH%
+  # - Download COM Server
+  - ps: Start-FileDownload "https://github.com/go-ole/test-com-server/releases/download/v1.0.2/test-com-server-${env:DOWNLOADPLATFORM}.zip"
+  - 7z e test-com-server-%DOWNLOADPLATFORM%.zip -oc:\gopath\src\github.com\go-ole\go-ole > NUL
+  - c:\gopath\src\github.com\go-ole\go-ole\build\register-assembly.bat
+  # - set
+  - go version
+  - go env
+  - go get -u golang.org/x/tools/cmd/cover
+  - go get -u golang.org/x/tools/cmd/godoc
+  - go get -u golang.org/x/tools/cmd/stringer
+
+build_script:
+  - cd c:\gopath\src\github.com\go-ole\go-ole
+  - go get -v -t ./...
+  - go build
+  - go test -v -cover ./...
+
+# disable automatic tests
+test: off
+
+# disable deployment
+deploy: off
diff --git a/vendor/github.com/go-stack/stack/.travis.yml b/vendor/github.com/go-stack/stack/.travis.yml
new file mode 100644
index 000000000..5c5a2b516
--- /dev/null
+++ b/vendor/github.com/go-stack/stack/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+sudo: false
+go:
+  - 1.7.x
+  - 1.8.x
+  - 1.9.x
+  - 1.10.x
+  - 1.11.x
+  - tip
+
+before_install:
+  - go get github.com/mattn/goveralls
+
+script:
+  - goveralls -service=travis-ci
diff --git a/vendor/github.com/go-stack/stack/README.md b/vendor/github.com/go-stack/stack/README.md
new file mode 100644
index 000000000..f11ccccaa
--- /dev/null
+++ b/vendor/github.com/go-stack/stack/README.md
@@ -0,0 +1,38 @@
+[![GoDoc](https://godoc.org/github.com/go-stack/stack?status.svg)](https://godoc.org/github.com/go-stack/stack)
+[![Go Report Card](https://goreportcard.com/badge/go-stack/stack)](https://goreportcard.com/report/go-stack/stack)
+[![TravisCI](https://travis-ci.org/go-stack/stack.svg?branch=master)](https://travis-ci.org/go-stack/stack)
+[![Coverage Status](https://coveralls.io/repos/github/go-stack/stack/badge.svg?branch=master)](https://coveralls.io/github/go-stack/stack?branch=master)
+
+# stack
+
+Package stack implements utilities to capture, manipulate, and format call
+stacks. It provides a simpler API than package runtime.
+
+The implementation takes care of the minutia and special cases of interpreting
+the program counter (pc) values returned by runtime.Callers.
+
+## Versioning
+
+Package stack publishes releases via [semver](http://semver.org/) compatible Git
+tags prefixed with a single 'v'. The master branch always contains the latest
+release. The develop branch contains unreleased commits.
+
+## Formatting
+
+Package stack's types implement fmt.Formatter, which provides a simple and
+flexible way to declaratively configure formatting when used with logging or
+error tracking packages.
+
+```go
+func DoTheThing() {
+    c := stack.Caller(0)
+    log.Print(c)          // "source.go:10"
+    log.Printf("%+v", c)  // "pkg/path/source.go:10"
+    log.Printf("%n", c)   // "DoTheThing"
+
+    s := stack.Trace().TrimRuntime()
+    log.Print(s)          // "[source.go:15 caller.go:42 main.go:14]"
+}
+```
+
+See the docs for all of the supported formatting options.
diff --git a/vendor/github.com/go-stack/stack/go.mod b/vendor/github.com/go-stack/stack/go.mod
new file mode 100644
index 000000000..96a53a109
--- /dev/null
+++ b/vendor/github.com/go-stack/stack/go.mod
@@ -0,0 +1 @@
+module github.com/go-stack/stack
diff --git a/vendor/github.com/golang/protobuf/LICENSE b/vendor/github.com/golang/protobuf/LICENSE
index 0f646931a..1b1b1921e 100644
--- a/vendor/github.com/golang/protobuf/LICENSE
+++ b/vendor/github.com/golang/protobuf/LICENSE
@@ -1,4 +1,7 @@
+Go support for Protocol Buffers - Google's data interchange format
+
 Copyright 2010 The Go Authors.  All rights reserved.
+https://github.com/golang/protobuf
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
diff --git a/vendor/github.com/golang/protobuf/proto/Makefile b/vendor/github.com/golang/protobuf/proto/Makefile
new file mode 100644
index 000000000..e2e0651a9
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/Makefile
@@ -0,0 +1,43 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+install:
+	go install
+
+test: install generate-test-pbs
+	go test
+
+
+generate-test-pbs:
+	make install
+	make -C testdata
+	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
+	make
diff --git a/vendor/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/golang/protobuf/proto/clone.go
index 3cd3249f7..e392575b3 100644
--- a/vendor/github.com/golang/protobuf/proto/clone.go
+++ b/vendor/github.com/golang/protobuf/proto/clone.go
@@ -35,39 +35,22 @@
 package proto
 
 import (
-	"fmt"
 	"log"
 	"reflect"
 	"strings"
 )
 
 // Clone returns a deep copy of a protocol buffer.
-func Clone(src Message) Message {
-	in := reflect.ValueOf(src)
+func Clone(pb Message) Message {
+	in := reflect.ValueOf(pb)
 	if in.IsNil() {
-		return src
+		return pb
 	}
-	out := reflect.New(in.Type().Elem())
-	dst := out.Interface().(Message)
-	Merge(dst, src)
-	return dst
-}
 
-// Merger is the interface representing objects that can merge messages of the same type.
-type Merger interface {
-	// Merge merges src into this message.
-	// Required and optional fields that are set in src will be set to that value in dst.
-	// Elements of repeated fields will be appended.
-	//
-	// Merge may panic if called with a different argument type than the receiver.
-	Merge(src Message)
-}
-
-// generatedMerger is the custom merge method that generated protos will have.
-// We must add this method since a generate Merge method will conflict with
-// many existing protos that have a Merge data field already defined.
-type generatedMerger interface {
-	XXX_Merge(src Message)
+	out := reflect.New(in.Type().Elem())
+	// out is empty so a merge is a deep copy.
+	mergeStruct(out.Elem(), in.Elem())
+	return out.Interface().(Message)
 }
 
 // Merge merges src into dst.
@@ -75,24 +58,17 @@ type generatedMerger interface {
 // Elements of repeated fields will be appended.
 // Merge panics if src and dst are not the same type, or if dst is nil.
 func Merge(dst, src Message) {
-	if m, ok := dst.(Merger); ok {
-		m.Merge(src)
-		return
-	}
-
 	in := reflect.ValueOf(src)
 	out := reflect.ValueOf(dst)
 	if out.IsNil() {
 		panic("proto: nil destination")
 	}
 	if in.Type() != out.Type() {
-		panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src))
+		// Explicit test prior to mergeStruct so that mistyped nils will fail
+		panic("proto: type mismatch")
 	}
 	if in.IsNil() {
-		return // Merge from nil src is a noop
-	}
-	if m, ok := dst.(generatedMerger); ok {
-		m.XXX_Merge(src)
+		// Merging nil into non-nil is a quiet no-op
 		return
 	}
 	mergeStruct(out.Elem(), in.Elem())
@@ -108,7 +84,7 @@ func mergeStruct(out, in reflect.Value) {
 		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
 	}
 
-	if emIn, err := extendable(in.Addr().Interface()); err == nil {
+	if emIn, ok := extendable(in.Addr().Interface()); ok {
 		emOut, _ := extendable(out.Addr().Interface())
 		mIn, muIn := emIn.extensionsRead()
 		if mIn != nil {
diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go
index d9aa3c42d..aa207298f 100644
--- a/vendor/github.com/golang/protobuf/proto/decode.go
+++ b/vendor/github.com/golang/protobuf/proto/decode.go
@@ -39,6 +39,8 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"os"
+	"reflect"
 )
 
 // errOverflow is returned when an integer is too large to be represented.
@@ -48,6 +50,10 @@ var errOverflow = errors.New("proto: integer overflow")
 // wire type is encountered. It does not get returned to user code.
 var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
 
+// The fundamental decoders that interpret bytes on the wire.
+// Those that take integer types all return uint64 and are
+// therefore of type valueDecoder.
+
 // DecodeVarint reads a varint-encoded integer from the slice.
 // It returns the integer and the number of bytes consumed, or
 // zero if there is not enough.
@@ -261,6 +267,9 @@ func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
 	return
 }
 
+// These are not ValueDecoders: they produce an array of bytes or a string.
+// bytes, embedded messages
+
 // DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
 // This is the format used for the bytes protocol buffer
 // type and for embedded messages.
@@ -302,29 +311,81 @@ func (p *Buffer) DecodeStringBytes() (s string, err error) {
 	return string(buf), nil
 }
 
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+// If the protocol buffer has extensions, and the field matches, add it as an extension.
+// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
+func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
+	oi := o.index
+
+	err := o.skip(t, tag, wire)
+	if err != nil {
+		return err
+	}
+
+	if !unrecField.IsValid() {
+		return nil
+	}
+
+	ptr := structPointer_Bytes(base, unrecField)
+
+	// Add the skipped field to struct field
+	obuf := o.buf
+
+	o.buf = *ptr
+	o.EncodeVarint(uint64(tag<<3 | wire))
+	*ptr = append(o.buf, obuf[oi:o.index]...)
+
+	o.buf = obuf
+
+	return nil
+}
+
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
+
+	var u uint64
+	var err error
+
+	switch wire {
+	case WireVarint:
+		_, err = o.DecodeVarint()
+	case WireFixed64:
+		_, err = o.DecodeFixed64()
+	case WireBytes:
+		_, err = o.DecodeRawBytes(false)
+	case WireFixed32:
+		_, err = o.DecodeFixed32()
+	case WireStartGroup:
+		for {
+			u, err = o.DecodeVarint()
+			if err != nil {
+				break
+			}
+			fwire := int(u & 0x7)
+			if fwire == WireEndGroup {
+				break
+			}
+			ftag := int(u >> 3)
+			err = o.skip(t, ftag, fwire)
+			if err != nil {
+				break
+			}
+		}
+	default:
+		err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
+	}
+	return err
+}
+
 // Unmarshaler is the interface representing objects that can
-// unmarshal themselves.  The argument points to data that may be
+// unmarshal themselves.  The method should reset the receiver before
+// decoding starts.  The argument points to data that may be
 // overwritten, so implementations should not keep references to the
 // buffer.
-// Unmarshal implementations should not clear the receiver.
-// Any unmarshaled data should be merged into the receiver.
-// Callers of Unmarshal that do not want to retain existing data
-// should Reset the receiver before calling Unmarshal.
 type Unmarshaler interface {
 	Unmarshal([]byte) error
 }
 
-// newUnmarshaler is the interface representing objects that can
-// unmarshal themselves. The semantics are identical to Unmarshaler.
-//
-// This exists to support protoc-gen-go generated messages.
-// The proto package will stop type-asserting to this interface in the future.
-//
-// DO NOT DEPEND ON THIS.
-type newUnmarshaler interface {
-	XXX_Unmarshal([]byte) error
-}
-
 // Unmarshal parses the protocol buffer representation in buf and places the
 // decoded result in pb.  If the struct underlying pb does not match
 // the data in buf, the results can be unpredictable.
@@ -334,13 +395,7 @@ type newUnmarshaler interface {
 // to preserve and append to existing data.
 func Unmarshal(buf []byte, pb Message) error {
 	pb.Reset()
-	if u, ok := pb.(newUnmarshaler); ok {
-		return u.XXX_Unmarshal(buf)
-	}
-	if u, ok := pb.(Unmarshaler); ok {
-		return u.Unmarshal(buf)
-	}
-	return NewBuffer(buf).Unmarshal(pb)
+	return UnmarshalMerge(buf, pb)
 }
 
 // UnmarshalMerge parses the protocol buffer representation in buf and
@@ -350,16 +405,8 @@ func Unmarshal(buf []byte, pb Message) error {
 // UnmarshalMerge merges into existing data in pb.
 // Most code should use Unmarshal instead.
 func UnmarshalMerge(buf []byte, pb Message) error {
-	if u, ok := pb.(newUnmarshaler); ok {
-		return u.XXX_Unmarshal(buf)
-	}
+	// If the object can unmarshal itself, let it.
 	if u, ok := pb.(Unmarshaler); ok {
-		// NOTE: The history of proto have unfortunately been inconsistent
-		// whether Unmarshaler should or should not implicitly clear itself.
-		// Some implementations do, most do not.
-		// Thus, calling this here may or may not do what people want.
-		//
-		// See https://github.com/golang/protobuf/issues/424
 		return u.Unmarshal(buf)
 	}
 	return NewBuffer(buf).Unmarshal(pb)
@@ -375,17 +422,12 @@ func (p *Buffer) DecodeMessage(pb Message) error {
 }
 
 // DecodeGroup reads a tag-delimited group from the Buffer.
-// StartGroup tag is already consumed. This function consumes
-// EndGroup tag.
 func (p *Buffer) DecodeGroup(pb Message) error {
-	b := p.buf[p.index:]
-	x, y := findEndGroup(b)
-	if x < 0 {
-		return io.ErrUnexpectedEOF
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
 	}
-	err := Unmarshal(b[:x], pb)
-	p.index += y
-	return err
+	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
 }
 
 // Unmarshal parses the protocol buffer representation in the
@@ -396,33 +438,533 @@ func (p *Buffer) DecodeGroup(pb Message) error {
 // Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
 func (p *Buffer) Unmarshal(pb Message) error {
 	// If the object can unmarshal itself, let it.
-	if u, ok := pb.(newUnmarshaler); ok {
-		err := u.XXX_Unmarshal(p.buf[p.index:])
-		p.index = len(p.buf)
-		return err
-	}
 	if u, ok := pb.(Unmarshaler); ok {
-		// NOTE: The history of proto have unfortunately been inconsistent
-		// whether Unmarshaler should or should not implicitly clear itself.
-		// Some implementations do, most do not.
-		// Thus, calling this here may or may not do what people want.
-		//
-		// See https://github.com/golang/protobuf/issues/424
 		err := u.Unmarshal(p.buf[p.index:])
 		p.index = len(p.buf)
 		return err
 	}
 
-	// Slow workaround for messages that aren't Unmarshalers.
-	// This includes some hand-coded .pb.go files and
-	// bootstrap protos.
-	// TODO: fix all of those and then add Unmarshal to
-	// the Message interface. Then:
-	// The cast above and code below can be deleted.
-	// The old unmarshaler can be deleted.
-	// Clients can call Unmarshal directly (can already do that, actually).
-	var info InternalMessageInfo
-	err := info.Unmarshal(pb, p.buf[p.index:])
-	p.index = len(p.buf)
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
+	}
+
+	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
+
+	if collectStats {
+		stats.Decode++
+	}
+
+	return err
+}
+
+// unmarshalType does the work of unmarshaling a structure.
+func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
+	var state errorState
+	required, reqFields := prop.reqCount, uint64(0)
+
+	var err error
+	for err == nil && o.index < len(o.buf) {
+		oi := o.index
+		var u uint64
+		u, err = o.DecodeVarint()
+		if err != nil {
+			break
+		}
+		wire := int(u & 0x7)
+		if wire == WireEndGroup {
+			if is_group {
+				if required > 0 {
+					// Not enough information to determine the exact field.
+					// (See below.)
+					return &RequiredNotSetError{"{Unknown}"}
+				}
+				return nil // input is satisfied
+			}
+			return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
+		}
+		tag := int(u >> 3)
+		if tag <= 0 {
+			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
+		}
+		fieldnum, ok := prop.decoderTags.get(tag)
+		if !ok {
+			// Maybe it's an extension?
+			if prop.extendable {
+				if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
+					if err = o.skip(st, tag, wire); err == nil {
+						extmap := e.extensionsWrite()
+						ext := extmap[int32(tag)] // may be missing
+						ext.enc = append(ext.enc, o.buf[oi:o.index]...)
+						extmap[int32(tag)] = ext
+					}
+					continue
+				}
+			}
+			// Maybe it's a oneof?
+			if prop.oneofUnmarshaler != nil {
+				m := structPointer_Interface(base, st).(Message)
+				// First return value indicates whether tag is a oneof field.
+				ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
+				if err == ErrInternalBadWireType {
+					// Map the error to something more descriptive.
+					// Do the formatting here to save generated code space.
+					err = fmt.Errorf("bad wiretype for oneof field in %T", m)
+				}
+				if ok {
+					continue
+				}
+			}
+			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
+			continue
+		}
+		p := prop.Prop[fieldnum]
+
+		if p.dec == nil {
+			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
+			continue
+		}
+		dec := p.dec
+		if wire != WireStartGroup && wire != p.WireType {
+			if wire == WireBytes && p.packedDec != nil {
+				// a packable field
+				dec = p.packedDec
+			} else {
+				err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
+				continue
+			}
+		}
+		decErr := dec(o, p, base)
+		if decErr != nil && !state.shouldContinue(decErr, p) {
+			err = decErr
+		}
+		if err == nil && p.Required {
+			// Successfully decoded a required field.
+			if tag <= 64 {
+				// use bitmap for fields 1-64 to catch field reuse.
+				var mask uint64 = 1 << uint64(tag-1)
+				if reqFields&mask == 0 {
+					// new required field
+					reqFields |= mask
+					required--
+				}
+			} else {
+				// This is imprecise. It can be fooled by a required field
+				// with a tag > 64 that is encoded twice; that's very rare.
+				// A fully correct implementation would require allocating
+				// a data structure, which we would like to avoid.
+				required--
+			}
+		}
+	}
+	if err == nil {
+		if is_group {
+			return io.ErrUnexpectedEOF
+		}
+		if state.err != nil {
+			return state.err
+		}
+		if required > 0 {
+			// Not enough information to determine the exact field. If we use extra
+			// CPU, we could determine the field only if the missing required field
+			// has a tag <= 64 and we check reqFields.
+			return &RequiredNotSetError{"{Unknown}"}
+		}
+	}
+	return err
+}
+
+// Individual type decoders
+// For each,
+//	u is the decoded value,
+//	v is a pointer to the field (pointer) in the struct
+
+// Sizes of the pools to allocate inside the Buffer.
+// The goal is modest amortization and allocation
+// on at least 16-byte boundaries.
+const (
+	boolPoolSize   = 16
+	uint32PoolSize = 8
+	uint64PoolSize = 4
+)
+
+// Decode a bool.
+func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	if len(o.bools) == 0 {
+		o.bools = make([]bool, boolPoolSize)
+	}
+	o.bools[0] = u != 0
+	*structPointer_Bool(base, p.field) = &o.bools[0]
+	o.bools = o.bools[1:]
+	return nil
+}
+
+func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	*structPointer_BoolVal(base, p.field) = u != 0
+	return nil
+}
+
+// Decode an int32.
+func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
+	return nil
+}
+
+func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
+	return nil
+}
+
+// Decode an int64.
+func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64_Set(structPointer_Word64(base, p.field), o, u)
+	return nil
+}
+
+func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
+	return nil
+}
+
+// Decode a string.
+func (o *Buffer) dec_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_String(base, p.field) = &s
+	return nil
+}
+
+func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_StringVal(base, p.field) = s
+	return nil
+}
+
+// Decode a slice of bytes ([]byte).
+func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	*structPointer_Bytes(base, p.field) = b
+	return nil
+}
+
+// Decode a slice of bools ([]bool).
+func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BoolSlice(base, p.field)
+	*v = append(*v, u != 0)
+	return nil
+}
+
+// Decode a slice of bools ([]bool) in packed format.
+func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
+	v := structPointer_BoolSlice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded bools
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+
+	y := *v
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		y = append(y, u != 0)
+	}
+
+	*v = y
+	return nil
+}
+
+// Decode a slice of int32s ([]int32).
+func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	structPointer_Word32Slice(base, p.field).Append(uint32(u))
+	return nil
+}
+
+// Decode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int32s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(uint32(u))
+	}
+	return nil
+}
+
+// Decode a slice of int64s ([]int64).
+func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+
+	structPointer_Word64Slice(base, p.field).Append(u)
+	return nil
+}
+
+// Decode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int64s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(u)
+	}
+	return nil
+}
+
+// Decode a slice of strings ([]string).
+func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	v := structPointer_StringSlice(base, p.field)
+	*v = append(*v, s)
+	return nil
+}
+
+// Decode a slice of slice of bytes ([][]byte).
+func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BytesSlice(base, p.field)
+	*v = append(*v, b)
+	return nil
+}
+
+// Decode a map field.
+func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+	oi := o.index       // index at the end of this map entry
+	o.index -= len(raw) // move buffer back to start of map entry
+
+	mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
+	if mptr.Elem().IsNil() {
+		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
+	}
+	v := mptr.Elem() // map[K]V
+
+	// Prepare addressable doubly-indirect placeholders for the key and value types.
+	// See enc_new_map for why.
+	keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
+	keybase := toStructPointer(keyptr.Addr())                  // **K
+
+	var valbase structPointer
+	var valptr reflect.Value
+	switch p.mtype.Elem().Kind() {
+	case reflect.Slice:
+		// []byte
+		var dummy []byte
+		valptr = reflect.ValueOf(&dummy)  // *[]byte
+		valbase = toStructPointer(valptr) // *[]byte
+	case reflect.Ptr:
+		// message; valptr is **Msg; need to allocate the intermediate pointer
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valptr.Set(reflect.New(valptr.Type().Elem()))
+		valbase = toStructPointer(valptr)
+	default:
+		// everything else
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valbase = toStructPointer(valptr.Addr())                   // **V
+	}
+
+	// Decode.
+	// This parses a restricted wire format, namely the encoding of a message
+	// with two fields. See enc_new_map for the format.
+	for o.index < oi {
+		// tagcode for key and value properties are always a single byte
+		// because they have tags 1 and 2.
+		tagcode := o.buf[o.index]
+		o.index++
+		switch tagcode {
+		case p.mkeyprop.tagcode[0]:
+			if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
+				return err
+			}
+		case p.mvalprop.tagcode[0]:
+			if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
+				return err
+			}
+		default:
+			// TODO: Should we silently skip this instead?
+			return fmt.Errorf("proto: bad map data tag %d", raw[0])
+		}
+	}
+	keyelem, valelem := keyptr.Elem(), valptr.Elem()
+	if !keyelem.IsValid() {
+		keyelem = reflect.Zero(p.mtype.Key())
+	}
+	if !valelem.IsValid() {
+		valelem = reflect.Zero(p.mtype.Elem())
+	}
+
+	v.SetMapIndex(keyelem, valelem)
+	return nil
+}
+
+// Decode a group.
+func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+	return o.unmarshalType(p.stype, p.sprop, true, bas)
+}
+
+// Decode an embedded message.
+func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
+	raw, e := o.DecodeRawBytes(false)
+	if e != nil {
+		return e
+	}
+
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := structPointer_Interface(bas, p.stype)
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, false, bas)
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}
+
+// Decode a slice of embedded messages.
+func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, false, base)
+}
+
+// Decode a slice of embedded groups.
+func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, true, base)
+}
+
+// Decode a slice of structs ([]*struct).
+func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
+	v := reflect.New(p.stype)
+	bas := toStructPointer(v)
+	structPointer_StructPointerSlice(base, p.field).Append(bas)
+
+	if is_group {
+		err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
+		return err
+	}
+
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := v.Interface()
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
+
+	o.buf = obuf
+	o.index = oi
+
 	return err
 }
diff --git a/vendor/github.com/golang/protobuf/proto/discard.go b/vendor/github.com/golang/protobuf/proto/discard.go
deleted file mode 100644
index dea2617ce..000000000
--- a/vendor/github.com/golang/protobuf/proto/discard.go
+++ /dev/null
@@ -1,350 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2017 The Go Authors.  All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"sync"
-	"sync/atomic"
-)
-
-type generatedDiscarder interface {
-	XXX_DiscardUnknown()
-}
-
-// DiscardUnknown recursively discards all unknown fields from this message
-// and all embedded messages.
-//
-// When unmarshaling a message with unrecognized fields, the tags and values
-// of such fields are preserved in the Message. This allows a later call to
-// marshal to be able to produce a message that continues to have those
-// unrecognized fields. To avoid this, DiscardUnknown is used to
-// explicitly clear the unknown fields after unmarshaling.
-//
-// For proto2 messages, the unknown fields of message extensions are only
-// discarded from messages that have been accessed via GetExtension.
-func DiscardUnknown(m Message) {
-	if m, ok := m.(generatedDiscarder); ok {
-		m.XXX_DiscardUnknown()
-		return
-	}
-	// TODO: Dynamically populate a InternalMessageInfo for legacy messages,
-	// but the master branch has no implementation for InternalMessageInfo,
-	// so it would be more work to replicate that approach.
-	discardLegacy(m)
-}
-
-// DiscardUnknown recursively discards all unknown fields.
-func (a *InternalMessageInfo) DiscardUnknown(m Message) {
-	di := atomicLoadDiscardInfo(&a.discard)
-	if di == nil {
-		di = getDiscardInfo(reflect.TypeOf(m).Elem())
-		atomicStoreDiscardInfo(&a.discard, di)
-	}
-	di.discard(toPointer(&m))
-}
-
-type discardInfo struct {
-	typ reflect.Type
-
-	initialized int32 // 0: only typ is valid, 1: everything is valid
-	lock        sync.Mutex
-
-	fields       []discardFieldInfo
-	unrecognized field
-}
-
-type discardFieldInfo struct {
-	field   field // Offset of field, guaranteed to be valid
-	discard func(src pointer)
-}
-
-var (
-	discardInfoMap  = map[reflect.Type]*discardInfo{}
-	discardInfoLock sync.Mutex
-)
-
-func getDiscardInfo(t reflect.Type) *discardInfo {
-	discardInfoLock.Lock()
-	defer discardInfoLock.Unlock()
-	di := discardInfoMap[t]
-	if di == nil {
-		di = &discardInfo{typ: t}
-		discardInfoMap[t] = di
-	}
-	return di
-}
-
-func (di *discardInfo) discard(src pointer) {
-	if src.isNil() {
-		return // Nothing to do.
-	}
-
-	if atomic.LoadInt32(&di.initialized) == 0 {
-		di.computeDiscardInfo()
-	}
-
-	for _, fi := range di.fields {
-		sfp := src.offset(fi.field)
-		fi.discard(sfp)
-	}
-
-	// For proto2 messages, only discard unknown fields in message extensions
-	// that have been accessed via GetExtension.
-	if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {
-		// Ignore lock since DiscardUnknown is not concurrency safe.
-		emm, _ := em.extensionsRead()
-		for _, mx := range emm {
-			if m, ok := mx.value.(Message); ok {
-				DiscardUnknown(m)
-			}
-		}
-	}
-
-	if di.unrecognized.IsValid() {
-		*src.offset(di.unrecognized).toBytes() = nil
-	}
-}
-
-func (di *discardInfo) computeDiscardInfo() {
-	di.lock.Lock()
-	defer di.lock.Unlock()
-	if di.initialized != 0 {
-		return
-	}
-	t := di.typ
-	n := t.NumField()
-
-	for i := 0; i < n; i++ {
-		f := t.Field(i)
-		if strings.HasPrefix(f.Name, "XXX_") {
-			continue
-		}
-
-		dfi := discardFieldInfo{field: toField(&f)}
-		tf := f.Type
-
-		// Unwrap tf to get its most basic type.
-		var isPointer, isSlice bool
-		if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
-			isSlice = true
-			tf = tf.Elem()
-		}
-		if tf.Kind() == reflect.Ptr {
-			isPointer = true
-			tf = tf.Elem()
-		}
-		if isPointer && isSlice && tf.Kind() != reflect.Struct {
-			panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name))
-		}
-
-		switch tf.Kind() {
-		case reflect.Struct:
-			switch {
-			case !isPointer:
-				panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name))
-			case isSlice: // E.g., []*pb.T
-				di := getDiscardInfo(tf)
-				dfi.discard = func(src pointer) {
-					sps := src.getPointerSlice()
-					for _, sp := range sps {
-						if !sp.isNil() {
-							di.discard(sp)
-						}
-					}
-				}
-			default: // E.g., *pb.T
-				di := getDiscardInfo(tf)
-				dfi.discard = func(src pointer) {
-					sp := src.getPointer()
-					if !sp.isNil() {
-						di.discard(sp)
-					}
-				}
-			}
-		case reflect.Map:
-			switch {
-			case isPointer || isSlice:
-				panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name))
-			default: // E.g., map[K]V
-				if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)
-					dfi.discard = func(src pointer) {
-						sm := src.asPointerTo(tf).Elem()
-						if sm.Len() == 0 {
-							return
-						}
-						for _, key := range sm.MapKeys() {
-							val := sm.MapIndex(key)
-							DiscardUnknown(val.Interface().(Message))
-						}
-					}
-				} else {
-					dfi.discard = func(pointer) {} // Noop
-				}
-			}
-		case reflect.Interface:
-			// Must be oneof field.
-			switch {
-			case isPointer || isSlice:
-				panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name))
-			default: // E.g., interface{}
-				// TODO: Make this faster?
-				dfi.discard = func(src pointer) {
-					su := src.asPointerTo(tf).Elem()
-					if !su.IsNil() {
-						sv := su.Elem().Elem().Field(0)
-						if sv.Kind() == reflect.Ptr && sv.IsNil() {
-							return
-						}
-						switch sv.Type().Kind() {
-						case reflect.Ptr: // Proto struct (e.g., *T)
-							DiscardUnknown(sv.Interface().(Message))
-						}
-					}
-				}
-			}
-		default:
-			continue
-		}
-		di.fields = append(di.fields, dfi)
-	}
-
-	di.unrecognized = invalidField
-	if f, ok := t.FieldByName("XXX_unrecognized"); ok {
-		if f.Type != reflect.TypeOf([]byte{}) {
-			panic("expected XXX_unrecognized to be of type []byte")
-		}
-		di.unrecognized = toField(&f)
-	}
-
-	atomic.StoreInt32(&di.initialized, 1)
-}
-
-func discardLegacy(m Message) {
-	v := reflect.ValueOf(m)
-	if v.Kind() != reflect.Ptr || v.IsNil() {
-		return
-	}
-	v = v.Elem()
-	if v.Kind() != reflect.Struct {
-		return
-	}
-	t := v.Type()
-
-	for i := 0; i < v.NumField(); i++ {
-		f := t.Field(i)
-		if strings.HasPrefix(f.Name, "XXX_") {
-			continue
-		}
-		vf := v.Field(i)
-		tf := f.Type
-
-		// Unwrap tf to get its most basic type.
-		var isPointer, isSlice bool
-		if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
-			isSlice = true
-			tf = tf.Elem()
-		}
-		if tf.Kind() == reflect.Ptr {
-			isPointer = true
-			tf = tf.Elem()
-		}
-		if isPointer && isSlice && tf.Kind() != reflect.Struct {
-			panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name))
-		}
-
-		switch tf.Kind() {
-		case reflect.Struct:
-			switch {
-			case !isPointer:
-				panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name))
-			case isSlice: // E.g., []*pb.T
-				for j := 0; j < vf.Len(); j++ {
-					discardLegacy(vf.Index(j).Interface().(Message))
-				}
-			default: // E.g., *pb.T
-				discardLegacy(vf.Interface().(Message))
-			}
-		case reflect.Map:
-			switch {
-			case isPointer || isSlice:
-				panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name))
-			default: // E.g., map[K]V
-				tv := vf.Type().Elem()
-				if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)
-					for _, key := range vf.MapKeys() {
-						val := vf.MapIndex(key)
-						discardLegacy(val.Interface().(Message))
-					}
-				}
-			}
-		case reflect.Interface:
-			// Must be oneof field.
-			switch {
-			case isPointer || isSlice:
-				panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name))
-			default: // E.g., test_proto.isCommunique_Union interface
-				if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" {
-					vf = vf.Elem() // E.g., *test_proto.Communique_Msg
-					if !vf.IsNil() {
-						vf = vf.Elem()   // E.g., test_proto.Communique_Msg
-						vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value
-						if vf.Kind() == reflect.Ptr {
-							discardLegacy(vf.Interface().(Message))
-						}
-					}
-				}
-			}
-		}
-	}
-
-	if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() {
-		if vf.Type() != reflect.TypeOf([]byte{}) {
-			panic("expected XXX_unrecognized to be of type []byte")
-		}
-		vf.Set(reflect.ValueOf([]byte(nil)))
-	}
-
-	// For proto2 messages, only discard unknown fields in message extensions
-	// that have been accessed via GetExtension.
-	if em, err := extendable(m); err == nil {
-		// Ignore lock since discardLegacy is not concurrency safe.
-		emm, _ := em.extensionsRead()
-		for _, mx := range emm {
-			if m, ok := mx.value.(Message); ok {
-				discardLegacy(m)
-			}
-		}
-	}
-}
diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go
index 3abfed2cf..2b30f8462 100644
--- a/vendor/github.com/golang/protobuf/proto/encode.go
+++ b/vendor/github.com/golang/protobuf/proto/encode.go
@@ -37,9 +37,28 @@ package proto
 
 import (
 	"errors"
+	"fmt"
 	"reflect"
+	"sort"
 )
 
+// RequiredNotSetError is the error returned if Marshal is called with
+// a protocol buffer struct whose required fields have not
+// all been initialized. It is also the error returned if Unmarshal is
+// called with an encoded protocol buffer that does not include all the
+// required fields.
+//
+// When printed, RequiredNotSetError reports the first unset required field in a
+// message. If the field cannot be precisely determined, it is reported as
+// "{Unknown}".
+type RequiredNotSetError struct {
+	field string
+}
+
+func (e *RequiredNotSetError) Error() string {
+	return fmt.Sprintf("proto: required field %q not set", e.field)
+}
+
 var (
 	// errRepeatedHasNil is the error returned if Marshal is called with
 	// a struct with a repeated field containing a nil element.
@@ -63,6 +82,10 @@ var (
 
 const maxVarintBytes = 10 // maximum length of a varint
 
+// maxMarshalSize is the largest allowed size of an encoded protobuf,
+// since C++ and Java use signed int32s for the size.
+const maxMarshalSize = 1<<31 - 1
+
 // EncodeVarint returns the varint encoding of x.
 // This is the format for the
 // int32, int64, uint32, uint64, bool, and enum
@@ -96,27 +119,18 @@ func (p *Buffer) EncodeVarint(x uint64) error {
 
 // SizeVarint returns the varint encoding size of an integer.
 func SizeVarint(x uint64) int {
-	switch {
-	case x < 1<<7:
-		return 1
-	case x < 1<<14:
-		return 2
-	case x < 1<<21:
-		return 3
-	case x < 1<<28:
-		return 4
-	case x < 1<<35:
-		return 5
-	case x < 1<<42:
-		return 6
-	case x < 1<<49:
-		return 7
-	case x < 1<<56:
-		return 8
-	case x < 1<<63:
-		return 9
-	}
-	return 10
+	return sizeVarint(x)
+}
+
+func sizeVarint(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
 }
 
 // EncodeFixed64 writes a 64-bit integer to the Buffer.
@@ -135,6 +149,10 @@ func (p *Buffer) EncodeFixed64(x uint64) error {
 	return nil
 }
 
+func sizeFixed64(x uint64) int {
+	return 8
+}
+
 // EncodeFixed32 writes a 32-bit integer to the Buffer.
 // This is the format for the
 // fixed32, sfixed32, and float protocol buffer types.
@@ -147,6 +165,10 @@ func (p *Buffer) EncodeFixed32(x uint64) error {
 	return nil
 }
 
+func sizeFixed32(x uint64) int {
+	return 4
+}
+
 // EncodeZigzag64 writes a zigzag-encoded 64-bit integer
 // to the Buffer.
 // This is the format used for the sint64 protocol buffer type.
@@ -155,6 +177,10 @@ func (p *Buffer) EncodeZigzag64(x uint64) error {
 	return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
 }
 
+func sizeZigzag64(x uint64) int {
+	return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+
 // EncodeZigzag32 writes a zigzag-encoded 32-bit integer
 // to the Buffer.
 // This is the format used for the sint32 protocol buffer type.
@@ -163,6 +189,10 @@ func (p *Buffer) EncodeZigzag32(x uint64) error {
 	return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
 }
 
+func sizeZigzag32(x uint64) int {
+	return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
 // EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
 // This is the format used for the bytes protocol buffer
 // type and for embedded messages.
@@ -172,6 +202,11 @@ func (p *Buffer) EncodeRawBytes(b []byte) error {
 	return nil
 }
 
+func sizeRawBytes(b []byte) int {
+	return sizeVarint(uint64(len(b))) +
+		len(b)
+}
+
 // EncodeStringBytes writes an encoded string to the Buffer.
 // This is the format used for the proto2 string type.
 func (p *Buffer) EncodeStringBytes(s string) error {
@@ -180,17 +215,319 @@ func (p *Buffer) EncodeStringBytes(s string) error {
 	return nil
 }
 
+func sizeStringBytes(s string) int {
+	return sizeVarint(uint64(len(s))) +
+		len(s)
+}
+
 // Marshaler is the interface representing objects that can marshal themselves.
 type Marshaler interface {
 	Marshal() ([]byte, error)
 }
 
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, returning the data.
+func Marshal(pb Message) ([]byte, error) {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		return m.Marshal()
+	}
+	p := NewBuffer(nil)
+	err := p.Marshal(pb)
+	if p.buf == nil && err == nil {
+		// Return a non-nil slice on success.
+		return []byte{}, nil
+	}
+	return p.buf, err
+}
+
 // EncodeMessage writes the protocol buffer to the Buffer,
 // prefixed by a varint-encoded length.
 func (p *Buffer) EncodeMessage(pb Message) error {
-	siz := Size(pb)
-	p.EncodeVarint(uint64(siz))
-	return p.Marshal(pb)
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		var state errorState
+		err = p.enc_len_struct(GetProperties(t.Elem()), base, &state)
+	}
+	return err
+}
+
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, writing the result to the
+// Buffer.
+func (p *Buffer) Marshal(pb Message) error {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		data, err := m.Marshal()
+		p.buf = append(p.buf, data...)
+		return err
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		err = p.enc_struct(GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		(stats).Encode++ // Parens are to work around a goimports bug.
+	}
+
+	if len(p.buf) > maxMarshalSize {
+		return ErrTooLarge
+	}
+	return err
+}
+
+// Size returns the encoded size of a protocol buffer.
+func Size(pb Message) (n int) {
+	// Can the object marshal itself?  If so, Size is slow.
+	// TODO: add Size to Marshaler, or add a Sizer interface.
+	if m, ok := pb.(Marshaler); ok {
+		b, _ := m.Marshal()
+		return len(b)
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return 0
+	}
+	if err == nil {
+		n = size_struct(GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		(stats).Size++ // Parens are to work around a goimports bug.
+	}
+
+	return
+}
+
+// Individual type encoders.
+
+// Encode a bool.
+func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := 0
+	if *v {
+		x = 1
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, 1)
+	return nil
+}
+
+func size_bool(p *Properties, base structPointer) int {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+func size_proto3_bool(p *Properties, base structPointer) int {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v && !p.oneof {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+// Encode an int32.
+func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return ErrNil
+	}
+	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return 0
+	}
+	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+func size_proto3_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode a uint32.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return ErrNil
+	}
+	x := word32_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_uint32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return 0
+	}
+	x := word32_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+func size_proto3_uint32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode an int64.
+func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return ErrNil
+	}
+	x := word64_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func size_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return 0
+	}
+	x := word64_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+func size_proto3_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+// Encode a string.
+func (o *Buffer) enc_string(p *Properties, base structPointer) error {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := *v
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(x)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(v)
+	return nil
+}
+
+func size_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return 0
+	}
+	x := *v
+	n += len(p.tagcode)
+	n += sizeStringBytes(x)
+	return
+}
+
+func size_proto3_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeStringBytes(v)
+	return
 }
 
 // All protocol buffer fields are nillable, but be careful.
@@ -201,3 +538,825 @@ func isNil(v reflect.Value) bool {
 	}
 	return false
 }
+
+// Encode a message struct.
+func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return ErrNil
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, err := m.Marshal()
+		if err != nil && !state.shouldContinue(err, nil) {
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(data)
+		return state.err
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	return o.enc_len_struct(p.sprop, structp, &state)
+}
+
+func size_struct_message(p *Properties, base structPointer) int {
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return 0
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, _ := m.Marshal()
+		n0 := len(p.tagcode)
+		n1 := sizeRawBytes(data)
+		return n0 + n1
+	}
+
+	n0 := len(p.tagcode)
+	n1 := size_struct(p.sprop, structp)
+	n2 := sizeVarint(uint64(n1)) // size of encoded length
+	return n0 + n1 + n2
+}
+
+// Encode a group struct.
+func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return ErrNil
+	}
+
+	o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	err := o.enc_struct(p.sprop, b)
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return state.err
+}
+
+func size_struct_group(p *Properties, base structPointer) (n int) {
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return 0
+	}
+
+	n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	n += size_struct(p.sprop, b)
+	n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return
+}
+
+// Encode a slice of bools ([]bool).
+func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	for _, x := range s {
+		o.buf = append(o.buf, p.tagcode...)
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_bool(p *Properties, base structPointer) int {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
+}
+
+// Encode a slice of bools ([]bool) in packed format.
+func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
+	for _, x := range s {
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(l))
+	n += l // each bool takes exactly one byte
+	return
+}
+
+// Encode a slice of bytes ([]byte).
+func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(s)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(s)
+	return nil
+}
+
+func size_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeRawBytes(s)
+	return
+}
+
+func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeRawBytes(s)
+	return
+}
+
+// Encode a slice of int32s ([]int32).
+func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(buf, uint64(x))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		bufSize += p.valSize(uint64(x))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of uint32s ([]uint32).
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := s.Index(i)
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_uint32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := s.Index(i)
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of uint32s ([]uint32) in packed format.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, uint64(s.Index(i)))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(uint64(s.Index(i)))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of int64s ([]int64).
+func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		p.valEnc(o, s.Index(i))
+	}
+	return nil
+}
+
+func size_slice_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		n += p.valSize(s.Index(i))
+	}
+	return
+}
+
+// Encode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, s.Index(i))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(s.Index(i))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of slice of bytes ([][]byte).
+func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return 0
+	}
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeRawBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of strings ([]string).
+func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeStringBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_string(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeStringBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of message structs ([]*struct).
+func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return errRepeatedHasNil
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, err := m.Marshal()
+			if err != nil && !state.shouldContinue(err, nil) {
+				return err
+			}
+			o.buf = append(o.buf, p.tagcode...)
+			o.EncodeRawBytes(data)
+			continue
+		}
+
+		o.buf = append(o.buf, p.tagcode...)
+		err := o.enc_len_struct(p.sprop, structp, &state)
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return errRepeatedHasNil
+			}
+			return err
+		}
+	}
+	return state.err
+}
+
+func size_slice_struct_message(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return // return the size up to this point
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, _ := m.Marshal()
+			n += sizeRawBytes(data)
+			continue
+		}
+
+		n0 := size_struct(p.sprop, structp)
+		n1 := sizeVarint(uint64(n0)) // size of encoded length
+		n += n0 + n1
+	}
+	return
+}
+
+// Encode a slice of group structs ([]*struct).
+func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return errRepeatedHasNil
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+
+		err := o.enc_struct(p.sprop, b)
+
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return errRepeatedHasNil
+			}
+			return err
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	}
+	return state.err
+}
+
+func size_slice_struct_group(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return // return size up to this point
+		}
+
+		n += size_struct(p.sprop, b)
+	}
+	return
+}
+
+// Encode an extension map.
+func (o *Buffer) enc_map(p *Properties, base structPointer) error {
+	exts := structPointer_ExtMap(base, p.field)
+	if err := encodeExtensionsMap(*exts); err != nil {
+		return err
+	}
+
+	return o.enc_map_body(*exts)
+}
+
+func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
+	exts := structPointer_Extensions(base, p.field)
+
+	v, mu := exts.extensionsRead()
+	if v == nil {
+		return nil
+	}
+
+	mu.Lock()
+	defer mu.Unlock()
+	if err := encodeExtensionsMap(v); err != nil {
+		return err
+	}
+
+	return o.enc_map_body(v)
+}
+
+func (o *Buffer) enc_map_body(v map[int32]Extension) error {
+	// Fast-path for common cases: zero or one extensions.
+	if len(v) <= 1 {
+		for _, e := range v {
+			o.buf = append(o.buf, e.enc...)
+		}
+		return nil
+	}
+
+	// Sort keys to provide a deterministic encoding.
+	keys := make([]int, 0, len(v))
+	for k := range v {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+
+	for _, k := range keys {
+		o.buf = append(o.buf, v[int32(k)].enc...)
+	}
+	return nil
+}
+
+func size_map(p *Properties, base structPointer) int {
+	v := structPointer_ExtMap(base, p.field)
+	return extensionsMapSize(*v)
+}
+
+func size_exts(p *Properties, base structPointer) int {
+	v := structPointer_Extensions(base, p.field)
+	return extensionsSize(v)
+}
+
+// Encode a map field.
+func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
+	var state errorState // XXX: or do we need to plumb this through?
+
+	/*
+		A map defined as
+			map<key_type, value_type> map_field = N;
+		is encoded in the same way as
+			message MapFieldEntry {
+				key_type key = 1;
+				value_type value = 2;
+			}
+			repeated MapFieldEntry map_field = N;
+	*/
+
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
+	if v.Len() == 0 {
+		return nil
+	}
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	enc := func() error {
+		if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
+			return err
+		}
+		if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
+			return err
+		}
+		return nil
+	}
+
+	// Don't sort map keys. It is not required by the spec, and C++ doesn't do it.
+	for _, key := range v.MapKeys() {
+		val := v.MapIndex(key)
+
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		o.buf = append(o.buf, p.tagcode...)
+		if err := o.enc_len_thing(enc, &state); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func size_new_map(p *Properties, base structPointer) int {
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	n := 0
+	for _, key := range v.MapKeys() {
+		val := v.MapIndex(key)
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		// Tag codes for key and val are the responsibility of the sub-sizer.
+		keysize := p.mkeyprop.size(p.mkeyprop, keybase)
+		valsize := p.mvalprop.size(p.mvalprop, valbase)
+		entry := keysize + valsize
+		// Add on tag code and length of map entry itself.
+		n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry
+	}
+	return n
+}
+
+// mapEncodeScratch returns a new reflect.Value matching the map's value type,
+// and a structPointer suitable for passing to an encoder or sizer.
+func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
+	// Prepare addressable doubly-indirect placeholders for the key and value types.
+	// This is needed because the element-type encoders expect **T, but the map iteration produces T.
+
+	keycopy = reflect.New(mapType.Key()).Elem()                 // addressable K
+	keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
+	keyptr.Set(keycopy.Addr())                                  //
+	keybase = toStructPointer(keyptr.Addr())                    // **K
+
+	// Value types are more varied and require special handling.
+	switch mapType.Elem().Kind() {
+	case reflect.Slice:
+		// []byte
+		var dummy []byte
+		valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
+		valbase = toStructPointer(valcopy.Addr())
+	case reflect.Ptr:
+		// message; the generated field type is map[K]*Msg (so V is *Msg),
+		// so we only need one level of indirection.
+		valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
+		valbase = toStructPointer(valcopy.Addr())
+	default:
+		// everything else
+		valcopy = reflect.New(mapType.Elem()).Elem()                // addressable V
+		valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
+		valptr.Set(valcopy.Addr())                                  //
+		valbase = toStructPointer(valptr.Addr())                    // **V
+	}
+	return
+}
+
+// Encode a struct.
+func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
+	var state errorState
+	// Encode fields in tag order so that decoders may use optimizations
+	// that depend on the ordering.
+	// https://developers.google.com/protocol-buffers/docs/encoding#order
+	for _, i := range prop.order {
+		p := prop.Prop[i]
+		if p.enc != nil {
+			err := p.enc(o, p, base)
+			if err != nil {
+				if err == ErrNil {
+					if p.Required && state.err == nil {
+						state.err = &RequiredNotSetError{p.Name}
+					}
+				} else if err == errRepeatedHasNil {
+					// Give more context to nil values in repeated fields.
+					return errors.New("repeated field " + p.OrigName + " has nil element")
+				} else if !state.shouldContinue(err, p) {
+					return err
+				}
+			}
+			if len(o.buf) > maxMarshalSize {
+				return ErrTooLarge
+			}
+		}
+	}
+
+	// Do oneof fields.
+	if prop.oneofMarshaler != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		if err := prop.oneofMarshaler(m, o); err == ErrNil {
+			return errOneofHasNil
+		} else if err != nil {
+			return err
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		if len(o.buf)+len(v) > maxMarshalSize {
+			return ErrTooLarge
+		}
+		if len(v) > 0 {
+			o.buf = append(o.buf, v...)
+		}
+	}
+
+	return state.err
+}
+
+func size_struct(prop *StructProperties, base structPointer) (n int) {
+	for _, i := range prop.order {
+		p := prop.Prop[i]
+		if p.size != nil {
+			n += p.size(p, base)
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		n += len(v)
+	}
+
+	// Factor in any oneof fields.
+	if prop.oneofSizer != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		n += prop.oneofSizer(m)
+	}
+
+	return
+}
+
+var zeroes [20]byte // longer than any conceivable sizeVarint
+
+// Encode a struct, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
+	return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
+}
+
+// Encode something, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
+	iLen := len(o.buf)
+	o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
+	iMsg := len(o.buf)
+	err := enc()
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	lMsg := len(o.buf) - iMsg
+	lLen := sizeVarint(uint64(lMsg))
+	switch x := lLen - (iMsg - iLen); {
+	case x > 0: // actual length is x bytes larger than the space we reserved
+		// Move msg x bytes right.
+		o.buf = append(o.buf, zeroes[:x]...)
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+	case x < 0: // actual length is x bytes smaller than the space we reserved
+		// Move msg x bytes left.
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+		o.buf = o.buf[:len(o.buf)+x] // x is negative
+	}
+	// Encode the length in the reserved space.
+	o.buf = o.buf[:iLen]
+	o.EncodeVarint(uint64(lMsg))
+	o.buf = o.buf[:len(o.buf)+lMsg]
+	return state.err
+}
+
+// errorState maintains the first error that occurs and updates that error
+// with additional context.
+type errorState struct {
+	err error
+}
+
+// shouldContinue reports whether encoding should continue upon encountering the
+// given error. If the error is RequiredNotSetError, shouldContinue returns true
+// and, if this is the first appearance of that error, remembers it for future
+// reporting.
+//
+// If prop is not nil, it may update any error with additional context about the
+// field with the error.
+func (s *errorState) shouldContinue(err error, prop *Properties) bool {
+	// Ignore unset required fields.
+	reqNotSet, ok := err.(*RequiredNotSetError)
+	if !ok {
+		return false
+	}
+	if s.err == nil {
+		if prop != nil {
+			err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
+		}
+		s.err = err
+	}
+	return true
+}
diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go
index d4db5a1c1..2ed1cf596 100644
--- a/vendor/github.com/golang/protobuf/proto/equal.go
+++ b/vendor/github.com/golang/protobuf/proto/equal.go
@@ -109,6 +109,15 @@ func equalStruct(v1, v2 reflect.Value) bool {
 				// set/unset mismatch
 				return false
 			}
+			b1, ok := f1.Interface().(raw)
+			if ok {
+				b2 := f2.Interface().(raw)
+				// RawMessage
+				if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
+					return false
+				}
+				continue
+			}
 			f1, f2 = f1.Elem(), f2.Elem()
 		}
 		if !equalAny(f1, f2, sprop.Prop[i]) {
@@ -137,7 +146,11 @@ func equalStruct(v1, v2 reflect.Value) bool {
 
 	u1 := uf.Bytes()
 	u2 := v2.FieldByName("XXX_unrecognized").Bytes()
-	return bytes.Equal(u1, u2)
+	if !bytes.Equal(u1, u2) {
+		return false
+	}
+
+	return true
 }
 
 // v1 and v2 are known to have the same type.
@@ -248,15 +261,6 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
 
 		m1, m2 := e1.value, e2.value
 
-		if m1 == nil && m2 == nil {
-			// Both have only encoded form.
-			if bytes.Equal(e1.enc, e2.enc) {
-				continue
-			}
-			// The bytes are different, but the extensions might still be
-			// equal. We need to decode them to compare.
-		}
-
 		if m1 != nil && m2 != nil {
 			// Both are unencoded.
 			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
@@ -272,12 +276,8 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
 			desc = m[extNum]
 		}
 		if desc == nil {
-			// If both have only encoded form and the bytes are the same,
-			// it is handled above. We get here when the bytes are different.
-			// We don't know how to decode it, so just compare them as byte
-			// slices.
 			log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
-			return false
+			continue
 		}
 		var err error
 		if m1 == nil {
diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go
index 816a3b9d6..eaad21831 100644
--- a/vendor/github.com/golang/protobuf/proto/extensions.go
+++ b/vendor/github.com/golang/protobuf/proto/extensions.go
@@ -38,7 +38,6 @@ package proto
 import (
 	"errors"
 	"fmt"
-	"io"
 	"reflect"
 	"strconv"
 	"sync"
@@ -92,29 +91,14 @@ func (n notLocker) Unlock() {}
 // extendable returns the extendableProto interface for the given generated proto message.
 // If the proto message has the old extension format, it returns a wrapper that implements
 // the extendableProto interface.
-func extendable(p interface{}) (extendableProto, error) {
-	switch p := p.(type) {
-	case extendableProto:
-		if isNilPtr(p) {
-			return nil, fmt.Errorf("proto: nil %T is not extendable", p)
-		}
-		return p, nil
-	case extendableProtoV1:
-		if isNilPtr(p) {
-			return nil, fmt.Errorf("proto: nil %T is not extendable", p)
-		}
-		return extensionAdapter{p}, nil
+func extendable(p interface{}) (extendableProto, bool) {
+	if ep, ok := p.(extendableProto); ok {
+		return ep, ok
 	}
-	// Don't allocate a specific error containing %T:
-	// this is the hot path for Clone and MarshalText.
-	return nil, errNotExtendable
-}
-
-var errNotExtendable = errors.New("proto: not an extendable proto.Message")
-
-func isNilPtr(x interface{}) bool {
-	v := reflect.ValueOf(x)
-	return v.Kind() == reflect.Ptr && v.IsNil()
+	if ep, ok := p.(extendableProtoV1); ok {
+		return extensionAdapter{ep}, ok
+	}
+	return nil, false
 }
 
 // XXX_InternalExtensions is an internal representation of proto extensions.
@@ -159,6 +143,9 @@ func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Loc
 	return e.p.extensionMap, &e.p.mu
 }
 
+var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
+var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
+
 // ExtensionDesc represents an extension specification.
 // Used in generated code from the protocol compiler.
 type ExtensionDesc struct {
@@ -192,8 +179,8 @@ type Extension struct {
 
 // SetRawExtension is for testing only.
 func SetRawExtension(base Message, id int32, b []byte) {
-	epb, err := extendable(base)
-	if err != nil {
+	epb, ok := extendable(base)
+	if !ok {
 		return
 	}
 	extmap := epb.extensionsWrite()
@@ -218,7 +205,7 @@ func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
 		pbi = ea.extendableProtoV1
 	}
 	if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
-		return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a)
+		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
 	}
 	// Check the range.
 	if !isExtensionField(pb, extension.Field) {
@@ -263,11 +250,85 @@ func extensionProperties(ed *ExtensionDesc) *Properties {
 	return prop
 }
 
+// encode encodes any unmarshaled (unencoded) extensions in e.
+func encodeExtensions(e *XXX_InternalExtensions) error {
+	m, mu := e.extensionsRead()
+	if m == nil {
+		return nil // fast path
+	}
+	mu.Lock()
+	defer mu.Unlock()
+	return encodeExtensionsMap(m)
+}
+
+// encode encodes any unmarshaled (unencoded) extensions in e.
+func encodeExtensionsMap(m map[int32]Extension) error {
+	for k, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		p := NewBuffer(nil)
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		if err := props.enc(p, props, toStructPointer(x)); err != nil {
+			return err
+		}
+		e.enc = p.buf
+		m[k] = e
+	}
+	return nil
+}
+
+func extensionsSize(e *XXX_InternalExtensions) (n int) {
+	m, mu := e.extensionsRead()
+	if m == nil {
+		return 0
+	}
+	mu.Lock()
+	defer mu.Unlock()
+	return extensionsMapSize(m)
+}
+
+func extensionsMapSize(m map[int32]Extension) (n int) {
+	for _, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			n += len(e.enc)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		n += props.size(props, toStructPointer(x))
+	}
+	return
+}
+
 // HasExtension returns whether the given extension is present in pb.
 func HasExtension(pb Message, extension *ExtensionDesc) bool {
 	// TODO: Check types, field numbers, etc.?
-	epb, err := extendable(pb)
-	if err != nil {
+	epb, ok := extendable(pb)
+	if !ok {
 		return false
 	}
 	extmap, mu := epb.extensionsRead()
@@ -275,15 +336,15 @@ func HasExtension(pb Message, extension *ExtensionDesc) bool {
 		return false
 	}
 	mu.Lock()
-	_, ok := extmap[extension.Field]
+	_, ok = extmap[extension.Field]
 	mu.Unlock()
 	return ok
 }
 
 // ClearExtension removes the given extension from pb.
 func ClearExtension(pb Message, extension *ExtensionDesc) {
-	epb, err := extendable(pb)
-	if err != nil {
+	epb, ok := extendable(pb)
+	if !ok {
 		return
 	}
 	// TODO: Check types, field numbers, etc.?
@@ -291,26 +352,16 @@ func ClearExtension(pb Message, extension *ExtensionDesc) {
 	delete(extmap, extension.Field)
 }
 
-// GetExtension retrieves a proto2 extended field from pb.
-//
-// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
-// then GetExtension parses the encoded field and returns a Go value of the specified type.
-// If the field is not present, then the default value is returned (if one is specified),
-// otherwise ErrMissingExtension is reported.
-//
-// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
-// then GetExtension returns the raw encoded bytes of the field extension.
+// GetExtension parses and returns the given extension of pb.
+// If the extension is not present and has no default value it returns ErrMissingExtension.
 func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
-	epb, err := extendable(pb)
-	if err != nil {
-		return nil, err
+	epb, ok := extendable(pb)
+	if !ok {
+		return nil, errors.New("proto: not an extendable proto")
 	}
 
-	if extension.ExtendedType != nil {
-		// can only check type if this is a complete descriptor
-		if err := checkExtensionTypes(epb, extension); err != nil {
-			return nil, err
-		}
+	if err := checkExtensionTypes(epb, extension); err != nil {
+		return nil, err
 	}
 
 	emap, mu := epb.extensionsRead()
@@ -337,11 +388,6 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
 		return e.value, nil
 	}
 
-	if extension.ExtensionType == nil {
-		// incomplete descriptor
-		return e.enc, nil
-	}
-
 	v, err := decodeExtension(e.enc, extension)
 	if err != nil {
 		return nil, err
@@ -359,11 +405,6 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
 // defaultExtensionValue returns the default value for extension.
 // If no default for an extension is defined ErrMissingExtension is returned.
 func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
-	if extension.ExtensionType == nil {
-		// incomplete descriptor, so no default
-		return nil, ErrMissingExtension
-	}
-
 	t := reflect.TypeOf(extension.ExtensionType)
 	props := extensionProperties(extension)
 
@@ -398,28 +439,31 @@ func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
 
 // decodeExtension decodes an extension encoded in b.
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
+	o := NewBuffer(b)
+
 	t := reflect.TypeOf(extension.ExtensionType)
-	unmarshal := typeUnmarshaler(t, extension.Tag)
+
+	props := extensionProperties(extension)
 
 	// t is a pointer to a struct, pointer to basic type or a slice.
-	// Allocate space to store the pointer/slice.
+	// Allocate a "field" to store the pointer/slice itself; the
+	// pointer/slice will be stored here. We pass
+	// the address of this field to props.dec.
+	// This passes a zero field and a *t and lets props.dec
+	// interpret it as a *struct{ x t }.
 	value := reflect.New(t).Elem()
 
-	var err error
 	for {
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
+		// Discard wire type and field number varint. It isn't needed.
+		if _, err := o.DecodeVarint(); err != nil {
+			return nil, err
 		}
-		b = b[n:]
-		wire := int(x) & 7
 
-		b, err = unmarshal(b, valToPointer(value.Addr()), wire)
-		if err != nil {
+		if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
 			return nil, err
 		}
 
-		if len(b) == 0 {
+		if o.index >= len(o.buf) {
 			break
 		}
 	}
@@ -429,9 +473,9 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 // GetExtensions returns a slice of the extensions present in pb that are also listed in es.
 // The returned slice has the same length as es; missing extensions will appear as nil elements.
 func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
-	epb, err := extendable(pb)
-	if err != nil {
-		return nil, err
+	epb, ok := extendable(pb)
+	if !ok {
+		return nil, errors.New("proto: not an extendable proto")
 	}
 	extensions = make([]interface{}, len(es))
 	for i, e := range es {
@@ -450,9 +494,9 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e
 // For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
 // just the Field field, which defines the extension's field number.
 func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
-	epb, err := extendable(pb)
-	if err != nil {
-		return nil, err
+	epb, ok := extendable(pb)
+	if !ok {
+		return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
 	}
 	registeredExtensions := RegisteredExtensions(pb)
 
@@ -479,9 +523,9 @@ func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
 
 // SetExtension sets the specified extension of pb to the specified value.
 func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
-	epb, err := extendable(pb)
-	if err != nil {
-		return err
+	epb, ok := extendable(pb)
+	if !ok {
+		return errors.New("proto: not an extendable proto")
 	}
 	if err := checkExtensionTypes(epb, extension); err != nil {
 		return err
@@ -506,8 +550,8 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error
 
 // ClearAllExtensions clears all extensions from pb.
 func ClearAllExtensions(pb Message) {
-	epb, err := extendable(pb)
-	if err != nil {
+	epb, ok := extendable(pb)
+	if !ok {
 		return
 	}
 	m := epb.extensionsWrite()
diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go
index 75565cc6d..1c225504a 100644
--- a/vendor/github.com/golang/protobuf/proto/lib.go
+++ b/vendor/github.com/golang/protobuf/proto/lib.go
@@ -273,67 +273,6 @@ import (
 	"sync"
 )
 
-// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
-// Marshal reports this when a required field is not initialized.
-// Unmarshal reports this when a required field is missing from the wire data.
-type RequiredNotSetError struct{ field string }
-
-func (e *RequiredNotSetError) Error() string {
-	if e.field == "" {
-		return fmt.Sprintf("proto: required field not set")
-	}
-	return fmt.Sprintf("proto: required field %q not set", e.field)
-}
-func (e *RequiredNotSetError) RequiredNotSet() bool {
-	return true
-}
-
-type invalidUTF8Error struct{ field string }
-
-func (e *invalidUTF8Error) Error() string {
-	if e.field == "" {
-		return "proto: invalid UTF-8 detected"
-	}
-	return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
-}
-func (e *invalidUTF8Error) InvalidUTF8() bool {
-	return true
-}
-
-// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
-// This error should not be exposed to the external API as such errors should
-// be recreated with the field information.
-var errInvalidUTF8 = &invalidUTF8Error{}
-
-// isNonFatal reports whether the error is either a RequiredNotSet error
-// or a InvalidUTF8 error.
-func isNonFatal(err error) bool {
-	if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
-		return true
-	}
-	if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
-		return true
-	}
-	return false
-}
-
-type nonFatal struct{ E error }
-
-// Merge merges err into nf and reports whether it was successful.
-// Otherwise it returns false for any fatal non-nil errors.
-func (nf *nonFatal) Merge(err error) (ok bool) {
-	if err == nil {
-		return true // not an error
-	}
-	if !isNonFatal(err) {
-		return false // fatal error
-	}
-	if nf.E == nil {
-		nf.E = err // store first instance of non-fatal error
-	}
-	return true
-}
-
 // Message is implemented by generated protocol buffer messages.
 type Message interface {
 	Reset()
@@ -370,7 +309,16 @@ type Buffer struct {
 	buf   []byte // encode/decode byte stream
 	index int    // read point
 
-	deterministic bool
+	// pools of basic types to amortize allocation.
+	bools   []bool
+	uint32s []uint32
+	uint64s []uint64
+
+	// extra pools, only used with pointer_reflect.go
+	int32s   []int32
+	int64s   []int64
+	float32s []float32
+	float64s []float64
 }
 
 // NewBuffer allocates a new Buffer and initializes its internal data to
@@ -395,30 +343,6 @@ func (p *Buffer) SetBuf(s []byte) {
 // Bytes returns the contents of the Buffer.
 func (p *Buffer) Bytes() []byte { return p.buf }
 
-// SetDeterministic sets whether to use deterministic serialization.
-//
-// Deterministic serialization guarantees that for a given binary, equal
-// messages will always be serialized to the same bytes. This implies:
-//
-//   - Repeated serialization of a message will return the same bytes.
-//   - Different processes of the same binary (which may be executing on
-//     different machines) will serialize equal messages to the same bytes.
-//
-// Note that the deterministic serialization is NOT canonical across
-// languages. It is not guaranteed to remain stable over time. It is unstable
-// across different builds with schema changes due to unknown fields.
-// Users who need canonical serialization (e.g., persistent storage in a
-// canonical form, fingerprinting, etc.) should define their own
-// canonicalization specification and implement their own serializer rather
-// than relying on this API.
-//
-// If deterministic serialization is requested, map entries will be sorted
-// by keys in lexographical order. This is an implementation detail and
-// subject to change.
-func (p *Buffer) SetDeterministic(deterministic bool) {
-	p.deterministic = deterministic
-}
-
 /*
  * Helper routines for simplifying the creation of optional fields of basic type.
  */
@@ -907,12 +831,22 @@ func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMes
 	return sf, false, nil
 }
 
-// mapKeys returns a sort.Interface to be used for sorting the map keys.
 // Map fields may have key types of non-float scalars, strings and enums.
+// The easiest way to sort them in some deterministic order is to use fmt.
+// If this turns out to be inefficient we can always consider other options,
+// such as doing a Schwartzian transform.
+
 func mapKeys(vs []reflect.Value) sort.Interface {
-	s := mapKeySorter{vs: vs}
+	s := mapKeySorter{
+		vs: vs,
+		// default Less function: textual comparison
+		less: func(a, b reflect.Value) bool {
+			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
+		},
+	}
 
-	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
+	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
+	// numeric keys are sorted numerically.
 	if len(vs) == 0 {
 		return s
 	}
@@ -921,12 +855,6 @@ func mapKeys(vs []reflect.Value) sort.Interface {
 		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
 	case reflect.Uint32, reflect.Uint64:
 		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
-	case reflect.Bool:
-		s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
-	case reflect.String:
-		s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
-	default:
-		panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
 	}
 
 	return s
@@ -967,13 +895,3 @@ const ProtoPackageIsVersion2 = true
 // ProtoPackageIsVersion1 is referenced from generated protocol buffer files
 // to assert that that code is compatible with this version of the proto package.
 const ProtoPackageIsVersion1 = true
-
-// InternalMessageInfo is a type used internally by generated .pb.go files.
-// This type is not intended to be used by non-generated code.
-// This type is not subject to any compatibility guarantee.
-type InternalMessageInfo struct {
-	marshal   *marshalInfo
-	unmarshal *unmarshalInfo
-	merge     *mergeInfo
-	discard   *discardInfo
-}
diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go
index 3b6ca41d5..fd982decd 100644
--- a/vendor/github.com/golang/protobuf/proto/message_set.go
+++ b/vendor/github.com/golang/protobuf/proto/message_set.go
@@ -42,7 +42,6 @@ import (
 	"fmt"
 	"reflect"
 	"sort"
-	"sync"
 )
 
 // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
@@ -95,7 +94,10 @@ func (ms *messageSet) find(pb Message) *_MessageSet_Item {
 }
 
 func (ms *messageSet) Has(pb Message) bool {
-	return ms.find(pb) != nil
+	if ms.find(pb) != nil {
+		return true
+	}
+	return false
 }
 
 func (ms *messageSet) Unmarshal(pb Message) error {
@@ -148,42 +150,46 @@ func skipVarint(buf []byte) []byte {
 // MarshalMessageSet encodes the extension map represented by m in the message set wire format.
 // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
 func MarshalMessageSet(exts interface{}) ([]byte, error) {
-	return marshalMessageSet(exts, false)
-}
-
-// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal.
-func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) {
+	var m map[int32]Extension
 	switch exts := exts.(type) {
 	case *XXX_InternalExtensions:
-		var u marshalInfo
-		siz := u.sizeMessageSet(exts)
-		b := make([]byte, 0, siz)
-		return u.appendMessageSet(b, exts, deterministic)
-
+		if err := encodeExtensions(exts); err != nil {
+			return nil, err
+		}
+		m, _ = exts.extensionsRead()
 	case map[int32]Extension:
-		// This is an old-style extension map.
-		// Wrap it in a new-style XXX_InternalExtensions.
-		ie := XXX_InternalExtensions{
-			p: &struct {
-				mu           sync.Mutex
-				extensionMap map[int32]Extension
-			}{
-				extensionMap: exts,
-			},
+		if err := encodeExtensionsMap(exts); err != nil {
+			return nil, err
 		}
-
-		var u marshalInfo
-		siz := u.sizeMessageSet(&ie)
-		b := make([]byte, 0, siz)
-		return u.appendMessageSet(b, &ie, deterministic)
-
+		m = exts
 	default:
 		return nil, errors.New("proto: not an extension map")
 	}
+
+	// Sort extension IDs to provide a deterministic encoding.
+	// See also enc_map in encode.go.
+	ids := make([]int, 0, len(m))
+	for id := range m {
+		ids = append(ids, int(id))
+	}
+	sort.Ints(ids)
+
+	ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
+	for _, id := range ids {
+		e := m[int32(id)]
+		// Remove the wire type and field number varint, as well as the length varint.
+		msg := skipVarint(skipVarint(e.enc))
+
+		ms.Item = append(ms.Item, &_MessageSet_Item{
+			TypeId:  Int32(int32(id)),
+			Message: msg,
+		})
+	}
+	return Marshal(ms)
 }
 
 // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
-// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
+// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
 func UnmarshalMessageSet(buf []byte, exts interface{}) error {
 	var m map[int32]Extension
 	switch exts := exts.(type) {
@@ -229,15 +235,7 @@ func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
 	var m map[int32]Extension
 	switch exts := exts.(type) {
 	case *XXX_InternalExtensions:
-		var mu sync.Locker
-		m, mu = exts.extensionsRead()
-		if m != nil {
-			// Keep the extensions map locked until we're done marshaling to prevent
-			// races between marshaling and unmarshaling the lazily-{en,de}coded
-			// values.
-			mu.Lock()
-			defer mu.Unlock()
-		}
+		m, _ = exts.extensionsRead()
 	case map[int32]Extension:
 		m = exts
 	default:
@@ -255,16 +253,15 @@ func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
 
 	for i, id := range ids {
 		ext := m[id]
+		if i > 0 {
+			b.WriteByte(',')
+		}
+
 		msd, ok := messageSetMap[id]
 		if !ok {
 			// Unknown type; we can't render it, so skip it.
 			continue
 		}
-
-		if i > 0 && b.Len() > 1 {
-			b.WriteByte(',')
-		}
-
 		fmt.Fprintf(&b, `"[%s]":`, msd.name)
 
 		x := ext.value
diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
index b6cad9083..fb512e2e1 100644
--- a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
+++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build purego appengine js
+// +build appengine js
 
 // This file contains an implementation of proto field accesses using package reflect.
 // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
@@ -38,13 +38,32 @@
 package proto
 
 import (
+	"math"
 	"reflect"
-	"sync"
 )
 
-const unsafeAllowed = false
+// A structPointer is a pointer to a struct.
+type structPointer struct {
+	v reflect.Value
+}
+
+// toStructPointer returns a structPointer equivalent to the given reflect value.
+// The reflect value must itself be a pointer to a struct.
+func toStructPointer(v reflect.Value) structPointer {
+	return structPointer{v}
+}
+
+// IsNil reports whether p is nil.
+func structPointer_IsNil(p structPointer) bool {
+	return p.v.IsNil()
+}
 
-// A field identifies a field in a struct, accessible from a pointer.
+// Interface returns the struct pointer as an interface value.
+func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
+	return p.v.Interface()
+}
+
+// A field identifies a field in a struct, accessible from a structPointer.
 // In this implementation, a field is identified by the sequence of field indices
 // passed to reflect's FieldByIndex.
 type field []int
@@ -57,301 +76,409 @@ func toField(f *reflect.StructField) field {
 // invalidField is an invalid field identifier.
 var invalidField = field(nil)
 
-// zeroField is a noop when calling pointer.offset.
-var zeroField = field([]int{})
-
 // IsValid reports whether the field identifier is valid.
 func (f field) IsValid() bool { return f != nil }
 
-// The pointer type is for the table-driven decoder.
-// The implementation here uses a reflect.Value of pointer type to
-// create a generic pointer. In pointer_unsafe.go we use unsafe
-// instead of reflect to implement the same (but faster) interface.
-type pointer struct {
-	v reflect.Value
-}
+// field returns the given field in the struct as a reflect value.
+func structPointer_field(p structPointer, f field) reflect.Value {
+	// Special case: an extension map entry with a value of type T
+	// passes a *T to the struct-handling code with a zero field,
+	// expecting that it will be treated as equivalent to *struct{ X T },
+	// which has the same memory layout. We have to handle that case
+	// specially, because reflect will panic if we call FieldByIndex on a
+	// non-struct.
+	if f == nil {
+		return p.v.Elem()
+	}
 
-// toPointer converts an interface of pointer type to a pointer
-// that points to the same target.
-func toPointer(i *Message) pointer {
-	return pointer{v: reflect.ValueOf(*i)}
+	return p.v.Elem().FieldByIndex(f)
 }
 
-// toAddrPointer converts an interface to a pointer that points to
-// the interface data.
-func toAddrPointer(i *interface{}, isptr bool) pointer {
-	v := reflect.ValueOf(*i)
-	u := reflect.New(v.Type())
-	u.Elem().Set(v)
-	return pointer{v: u}
+// ifield returns the given field in the struct as an interface value.
+func structPointer_ifield(p structPointer, f field) interface{} {
+	return structPointer_field(p, f).Addr().Interface()
 }
 
-// valToPointer converts v to a pointer.  v must be of pointer type.
-func valToPointer(v reflect.Value) pointer {
-	return pointer{v: v}
+// Bytes returns the address of a []byte field in the struct.
+func structPointer_Bytes(p structPointer, f field) *[]byte {
+	return structPointer_ifield(p, f).(*[]byte)
 }
 
-// offset converts from a pointer to a structure to a pointer to
-// one of its fields.
-func (p pointer) offset(f field) pointer {
-	return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
+// BytesSlice returns the address of a [][]byte field in the struct.
+func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
+	return structPointer_ifield(p, f).(*[][]byte)
 }
 
-func (p pointer) isNil() bool {
-	return p.v.IsNil()
+// Bool returns the address of a *bool field in the struct.
+func structPointer_Bool(p structPointer, f field) **bool {
+	return structPointer_ifield(p, f).(**bool)
 }
 
-// grow updates the slice s in place to make it one element longer.
-// s must be addressable.
-// Returns the (addressable) new element.
-func grow(s reflect.Value) reflect.Value {
-	n, m := s.Len(), s.Cap()
-	if n < m {
-		s.SetLen(n + 1)
-	} else {
-		s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem())))
-	}
-	return s.Index(n)
+// BoolVal returns the address of a bool field in the struct.
+func structPointer_BoolVal(p structPointer, f field) *bool {
+	return structPointer_ifield(p, f).(*bool)
 }
 
-func (p pointer) toInt64() *int64 {
-	return p.v.Interface().(*int64)
+// BoolSlice returns the address of a []bool field in the struct.
+func structPointer_BoolSlice(p structPointer, f field) *[]bool {
+	return structPointer_ifield(p, f).(*[]bool)
 }
-func (p pointer) toInt64Ptr() **int64 {
-	return p.v.Interface().(**int64)
-}
-func (p pointer) toInt64Slice() *[]int64 {
-	return p.v.Interface().(*[]int64)
-}
-
-var int32ptr = reflect.TypeOf((*int32)(nil))
 
-func (p pointer) toInt32() *int32 {
-	return p.v.Convert(int32ptr).Interface().(*int32)
+// String returns the address of a *string field in the struct.
+func structPointer_String(p structPointer, f field) **string {
+	return structPointer_ifield(p, f).(**string)
 }
 
-// The toInt32Ptr/Slice methods don't work because of enums.
-// Instead, we must use set/get methods for the int32ptr/slice case.
-/*
-	func (p pointer) toInt32Ptr() **int32 {
-		return p.v.Interface().(**int32)
+// StringVal returns the address of a string field in the struct.
+func structPointer_StringVal(p structPointer, f field) *string {
+	return structPointer_ifield(p, f).(*string)
 }
-	func (p pointer) toInt32Slice() *[]int32 {
-		return p.v.Interface().(*[]int32)
-}
-*/
-func (p pointer) getInt32Ptr() *int32 {
-	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
-		// raw int32 type
-		return p.v.Elem().Interface().(*int32)
-	}
-	// an enum
-	return p.v.Elem().Convert(int32PtrType).Interface().(*int32)
-}
-func (p pointer) setInt32Ptr(v int32) {
-	// Allocate value in a *int32. Possibly convert that to a *enum.
-	// Then assign it to a **int32 or **enum.
-	// Note: we can convert *int32 to *enum, but we can't convert
-	// **int32 to **enum!
-	p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem()))
-}
-
-// getInt32Slice copies []int32 from p as a new slice.
-// This behavior differs from the implementation in pointer_unsafe.go.
-func (p pointer) getInt32Slice() []int32 {
-	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
-		// raw int32 type
-		return p.v.Elem().Interface().([]int32)
-	}
-	// an enum
-	// Allocate a []int32, then assign []enum's values into it.
-	// Note: we can't convert []enum to []int32.
-	slice := p.v.Elem()
-	s := make([]int32, slice.Len())
-	for i := 0; i < slice.Len(); i++ {
-		s[i] = int32(slice.Index(i).Int())
-	}
-	return s
+
+// StringSlice returns the address of a []string field in the struct.
+func structPointer_StringSlice(p structPointer, f field) *[]string {
+	return structPointer_ifield(p, f).(*[]string)
 }
 
-// setInt32Slice copies []int32 into p as a new slice.
-// This behavior differs from the implementation in pointer_unsafe.go.
-func (p pointer) setInt32Slice(v []int32) {
-	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
-		// raw int32 type
-		p.v.Elem().Set(reflect.ValueOf(v))
-		return
-	}
-	// an enum
-	// Allocate a []enum, then assign []int32's values into it.
-	// Note: we can't convert []enum to []int32.
-	slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v))
-	for i, x := range v {
-		slice.Index(i).SetInt(int64(x))
-	}
-	p.v.Elem().Set(slice)
+// Extensions returns the address of an extension map field in the struct.
+func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
+	return structPointer_ifield(p, f).(*XXX_InternalExtensions)
 }
-func (p pointer) appendInt32Slice(v int32) {
-	grow(p.v.Elem()).SetInt(int64(v))
+
+// ExtMap returns the address of an extension map field in the struct.
+func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
+	return structPointer_ifield(p, f).(*map[int32]Extension)
 }
 
-func (p pointer) toUint64() *uint64 {
-	return p.v.Interface().(*uint64)
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
+	return structPointer_field(p, f).Addr()
 }
-func (p pointer) toUint64Ptr() **uint64 {
-	return p.v.Interface().(**uint64)
+
+// SetStructPointer writes a *struct field in the struct.
+func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
+	structPointer_field(p, f).Set(q.v)
 }
-func (p pointer) toUint64Slice() *[]uint64 {
-	return p.v.Interface().(*[]uint64)
+
+// GetStructPointer reads a *struct field in the struct.
+func structPointer_GetStructPointer(p structPointer, f field) structPointer {
+	return structPointer{structPointer_field(p, f)}
 }
-func (p pointer) toUint32() *uint32 {
-	return p.v.Interface().(*uint32)
+
+// StructPointerSlice the address of a []*struct field in the struct.
+func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
+	return structPointerSlice{structPointer_field(p, f)}
 }
-func (p pointer) toUint32Ptr() **uint32 {
-	return p.v.Interface().(**uint32)
+
+// A structPointerSlice represents the address of a slice of pointers to structs
+// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
+type structPointerSlice struct {
+	v reflect.Value
 }
-func (p pointer) toUint32Slice() *[]uint32 {
-	return p.v.Interface().(*[]uint32)
+
+func (p structPointerSlice) Len() int                  { return p.v.Len() }
+func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
+func (p structPointerSlice) Append(q structPointer) {
+	p.v.Set(reflect.Append(p.v, q.v))
 }
-func (p pointer) toBool() *bool {
-	return p.v.Interface().(*bool)
+
+var (
+	int32Type   = reflect.TypeOf(int32(0))
+	uint32Type  = reflect.TypeOf(uint32(0))
+	float32Type = reflect.TypeOf(float32(0))
+	int64Type   = reflect.TypeOf(int64(0))
+	uint64Type  = reflect.TypeOf(uint64(0))
+	float64Type = reflect.TypeOf(float64(0))
+)
+
+// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
+// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
+type word32 struct {
+	v reflect.Value
 }
-func (p pointer) toBoolPtr() **bool {
-	return p.v.Interface().(**bool)
+
+// IsNil reports whether p is nil.
+func word32_IsNil(p word32) bool {
+	return p.v.IsNil()
 }
-func (p pointer) toBoolSlice() *[]bool {
-	return p.v.Interface().(*[]bool)
+
+// Set sets p to point at a newly allocated word with bits set to x.
+func word32_Set(p word32, o *Buffer, x uint32) {
+	t := p.v.Type().Elem()
+	switch t {
+	case int32Type:
+		if len(o.int32s) == 0 {
+			o.int32s = make([]int32, uint32PoolSize)
+		}
+		o.int32s[0] = int32(x)
+		p.v.Set(reflect.ValueOf(&o.int32s[0]))
+		o.int32s = o.int32s[1:]
+		return
+	case uint32Type:
+		if len(o.uint32s) == 0 {
+			o.uint32s = make([]uint32, uint32PoolSize)
+		}
+		o.uint32s[0] = x
+		p.v.Set(reflect.ValueOf(&o.uint32s[0]))
+		o.uint32s = o.uint32s[1:]
+		return
+	case float32Type:
+		if len(o.float32s) == 0 {
+			o.float32s = make([]float32, uint32PoolSize)
+		}
+		o.float32s[0] = math.Float32frombits(x)
+		p.v.Set(reflect.ValueOf(&o.float32s[0]))
+		o.float32s = o.float32s[1:]
+		return
+	}
+
+	// must be enum
+	p.v.Set(reflect.New(t))
+	p.v.Elem().SetInt(int64(int32(x)))
 }
-func (p pointer) toFloat64() *float64 {
-	return p.v.Interface().(*float64)
+
+// Get gets the bits pointed at by p, as a uint32.
+func word32_Get(p word32) uint32 {
+	elem := p.v.Elem()
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
 }
-func (p pointer) toFloat64Ptr() **float64 {
-	return p.v.Interface().(**float64)
+
+// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32(p structPointer, f field) word32 {
+	return word32{structPointer_field(p, f)}
 }
-func (p pointer) toFloat64Slice() *[]float64 {
-	return p.v.Interface().(*[]float64)
+
+// A word32Val represents a field of type int32, uint32, float32, or enum.
+// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
+type word32Val struct {
+	v reflect.Value
 }
-func (p pointer) toFloat32() *float32 {
-	return p.v.Interface().(*float32)
+
+// Set sets *p to x.
+func word32Val_Set(p word32Val, x uint32) {
+	switch p.v.Type() {
+	case int32Type:
+		p.v.SetInt(int64(x))
+		return
+	case uint32Type:
+		p.v.SetUint(uint64(x))
+		return
+	case float32Type:
+		p.v.SetFloat(float64(math.Float32frombits(x)))
+		return
+	}
+
+	// must be enum
+	p.v.SetInt(int64(int32(x)))
 }
-func (p pointer) toFloat32Ptr() **float32 {
-	return p.v.Interface().(**float32)
+
+// Get gets the bits pointed at by p, as a uint32.
+func word32Val_Get(p word32Val) uint32 {
+	elem := p.v
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
 }
-func (p pointer) toFloat32Slice() *[]float32 {
-	return p.v.Interface().(*[]float32)
+
+// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
+func structPointer_Word32Val(p structPointer, f field) word32Val {
+	return word32Val{structPointer_field(p, f)}
 }
-func (p pointer) toString() *string {
-	return p.v.Interface().(*string)
+
+// A word32Slice is a slice of 32-bit values.
+// That is, v.Type() is []int32, []uint32, []float32, or []enum.
+type word32Slice struct {
+	v reflect.Value
 }
-func (p pointer) toStringPtr() **string {
-	return p.v.Interface().(**string)
+
+func (p word32Slice) Append(x uint32) {
+	n, m := p.v.Len(), p.v.Cap()
+	if n < m {
+		p.v.SetLen(n + 1)
+	} else {
+		t := p.v.Type().Elem()
+		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+	}
+	elem := p.v.Index(n)
+	switch elem.Kind() {
+	case reflect.Int32:
+		elem.SetInt(int64(int32(x)))
+	case reflect.Uint32:
+		elem.SetUint(uint64(x))
+	case reflect.Float32:
+		elem.SetFloat(float64(math.Float32frombits(x)))
+	}
 }
-func (p pointer) toStringSlice() *[]string {
-	return p.v.Interface().(*[]string)
+
+func (p word32Slice) Len() int {
+	return p.v.Len()
 }
-func (p pointer) toBytes() *[]byte {
-	return p.v.Interface().(*[]byte)
+
+func (p word32Slice) Index(i int) uint32 {
+	elem := p.v.Index(i)
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
 }
-func (p pointer) toBytesSlice() *[][]byte {
-	return p.v.Interface().(*[][]byte)
+
+// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
+func structPointer_Word32Slice(p structPointer, f field) word32Slice {
+	return word32Slice{structPointer_field(p, f)}
 }
-func (p pointer) toExtensions() *XXX_InternalExtensions {
-	return p.v.Interface().(*XXX_InternalExtensions)
+
+// word64 is like word32 but for 64-bit values.
+type word64 struct {
+	v reflect.Value
 }
-func (p pointer) toOldExtensions() *map[int32]Extension {
-	return p.v.Interface().(*map[int32]Extension)
+
+func word64_Set(p word64, o *Buffer, x uint64) {
+	t := p.v.Type().Elem()
+	switch t {
+	case int64Type:
+		if len(o.int64s) == 0 {
+			o.int64s = make([]int64, uint64PoolSize)
+		}
+		o.int64s[0] = int64(x)
+		p.v.Set(reflect.ValueOf(&o.int64s[0]))
+		o.int64s = o.int64s[1:]
+		return
+	case uint64Type:
+		if len(o.uint64s) == 0 {
+			o.uint64s = make([]uint64, uint64PoolSize)
+		}
+		o.uint64s[0] = x
+		p.v.Set(reflect.ValueOf(&o.uint64s[0]))
+		o.uint64s = o.uint64s[1:]
+		return
+	case float64Type:
+		if len(o.float64s) == 0 {
+			o.float64s = make([]float64, uint64PoolSize)
+		}
+		o.float64s[0] = math.Float64frombits(x)
+		p.v.Set(reflect.ValueOf(&o.float64s[0]))
+		o.float64s = o.float64s[1:]
+		return
+	}
+	panic("unreachable")
 }
-func (p pointer) getPointer() pointer {
-	return pointer{v: p.v.Elem()}
+
+func word64_IsNil(p word64) bool {
+	return p.v.IsNil()
 }
-func (p pointer) setPointer(q pointer) {
-	p.v.Elem().Set(q.v)
+
+func word64_Get(p word64) uint64 {
+	elem := p.v.Elem()
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return elem.Uint()
+	case reflect.Float64:
+		return math.Float64bits(elem.Float())
+	}
+	panic("unreachable")
 }
-func (p pointer) appendPointer(q pointer) {
-	grow(p.v.Elem()).Set(q.v)
+
+func structPointer_Word64(p structPointer, f field) word64 {
+	return word64{structPointer_field(p, f)}
 }
 
-// getPointerSlice copies []*T from p as a new []pointer.
-// This behavior differs from the implementation in pointer_unsafe.go.
-func (p pointer) getPointerSlice() []pointer {
-	if p.v.IsNil() {
-		return nil
-	}
-	n := p.v.Elem().Len()
-	s := make([]pointer, n)
-	for i := 0; i < n; i++ {
-		s[i] = pointer{v: p.v.Elem().Index(i)}
-	}
-	return s
+// word64Val is like word32Val but for 64-bit values.
+type word64Val struct {
+	v reflect.Value
 }
 
-// setPointerSlice copies []pointer into p as a new []*T.
-// This behavior differs from the implementation in pointer_unsafe.go.
-func (p pointer) setPointerSlice(v []pointer) {
-	if v == nil {
-		p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem())
+func word64Val_Set(p word64Val, o *Buffer, x uint64) {
+	switch p.v.Type() {
+	case int64Type:
+		p.v.SetInt(int64(x))
+		return
+	case uint64Type:
+		p.v.SetUint(x)
+		return
+	case float64Type:
+		p.v.SetFloat(math.Float64frombits(x))
 		return
 	}
-	s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v))
-	for _, p := range v {
-		s = reflect.Append(s, p.v)
-	}
-	p.v.Elem().Set(s)
+	panic("unreachable")
 }
 
-// getInterfacePointer returns a pointer that points to the
-// interface data of the interface pointed by p.
-func (p pointer) getInterfacePointer() pointer {
-	if p.v.Elem().IsNil() {
-		return pointer{v: p.v.Elem()}
+func word64Val_Get(p word64Val) uint64 {
+	elem := p.v
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return elem.Uint()
+	case reflect.Float64:
+		return math.Float64bits(elem.Float())
 	}
-	return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct
+	panic("unreachable")
 }
 
-func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
-	// TODO: check that p.v.Type().Elem() == t?
-	return p.v
+func structPointer_Word64Val(p structPointer, f field) word64Val {
+	return word64Val{structPointer_field(p, f)}
 }
 
-func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	return *p
-}
-func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	*p = v
-}
-func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	return *p
-}
-func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	*p = v
-}
-func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	return *p
+type word64Slice struct {
+	v reflect.Value
 }
-func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	*p = v
+
+func (p word64Slice) Append(x uint64) {
+	n, m := p.v.Len(), p.v.Cap()
+	if n < m {
+		p.v.SetLen(n + 1)
+	} else {
+		t := p.v.Type().Elem()
+		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+	}
+	elem := p.v.Index(n)
+	switch elem.Kind() {
+	case reflect.Int64:
+		elem.SetInt(int64(int64(x)))
+	case reflect.Uint64:
+		elem.SetUint(uint64(x))
+	case reflect.Float64:
+		elem.SetFloat(float64(math.Float64frombits(x)))
+	}
 }
-func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	return *p
+
+func (p word64Slice) Len() int {
+	return p.v.Len()
 }
-func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
-	atomicLock.Lock()
-	defer atomicLock.Unlock()
-	*p = v
+
+func (p word64Slice) Index(i int) uint64 {
+	elem := p.v.Index(i)
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return uint64(elem.Uint())
+	case reflect.Float64:
+		return math.Float64bits(float64(elem.Float()))
+	}
+	panic("unreachable")
 }
 
-var atomicLock sync.Mutex
+func structPointer_Word64Slice(p structPointer, f field) word64Slice {
+	return word64Slice{structPointer_field(p, f)}
+}
diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
index d55a335d9..6b5567d47 100644
--- a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
+++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build !purego,!appengine,!js
+// +build !appengine,!js
 
 // This file contains the implementation of the proto field accesses using package unsafe.
 
@@ -37,13 +37,38 @@ package proto
 
 import (
 	"reflect"
-	"sync/atomic"
 	"unsafe"
 )
 
-const unsafeAllowed = true
+// NOTE: These type_Foo functions would more idiomatically be methods,
+// but Go does not allow methods on pointer types, and we must preserve
+// some pointer type for the garbage collector. We use these
+// funcs with clunky names as our poor approximation to methods.
+//
+// An alternative would be
+//	type structPointer struct { p unsafe.Pointer }
+// but that does not registerize as well.
+
+// A structPointer is a pointer to a struct.
+type structPointer unsafe.Pointer
+
+// toStructPointer returns a structPointer equivalent to the given reflect value.
+func toStructPointer(v reflect.Value) structPointer {
+	return structPointer(unsafe.Pointer(v.Pointer()))
+}
+
+// IsNil reports whether p is nil.
+func structPointer_IsNil(p structPointer) bool {
+	return p == nil
+}
+
+// Interface returns the struct pointer, assumed to have element type t,
+// as an interface value.
+func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
+	return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
+}
 
-// A field identifies a field in a struct, accessible from a pointer.
+// A field identifies a field in a struct, accessible from a structPointer.
 // In this implementation, a field is identified by its byte offset from the start of the struct.
 type field uintptr
 
@@ -55,254 +80,191 @@ func toField(f *reflect.StructField) field {
 // invalidField is an invalid field identifier.
 const invalidField = ^field(0)
 
-// zeroField is a noop when calling pointer.offset.
-const zeroField = field(0)
-
 // IsValid reports whether the field identifier is valid.
 func (f field) IsValid() bool {
-	return f != invalidField
+	return f != ^field(0)
 }
 
-// The pointer type below is for the new table-driven encoder/decoder.
-// The implementation here uses unsafe.Pointer to create a generic pointer.
-// In pointer_reflect.go we use reflect instead of unsafe to implement
-// the same (but slower) interface.
-type pointer struct {
-	p unsafe.Pointer
+// Bytes returns the address of a []byte field in the struct.
+func structPointer_Bytes(p structPointer, f field) *[]byte {
+	return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// size of pointer
-var ptrSize = unsafe.Sizeof(uintptr(0))
-
-// toPointer converts an interface of pointer type to a pointer
-// that points to the same target.
-func toPointer(i *Message) pointer {
-	// Super-tricky - read pointer out of data word of interface value.
-	// Saves ~25ns over the equivalent:
-	// return valToPointer(reflect.ValueOf(*i))
-	return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
+// BytesSlice returns the address of a [][]byte field in the struct.
+func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
+	return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// toAddrPointer converts an interface to a pointer that points to
-// the interface data.
-func toAddrPointer(i *interface{}, isptr bool) pointer {
-	// Super-tricky - read or get the address of data word of interface value.
-	if isptr {
-		// The interface is of pointer type, thus it is a direct interface.
-		// The data word is the pointer data itself. We take its address.
-		return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
-	}
-	// The interface is not of pointer type. The data word is the pointer
-	// to the data.
-	return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
+// Bool returns the address of a *bool field in the struct.
+func structPointer_Bool(p structPointer, f field) **bool {
+	return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// valToPointer converts v to a pointer. v must be of pointer type.
-func valToPointer(v reflect.Value) pointer {
-	return pointer{p: unsafe.Pointer(v.Pointer())}
+// BoolVal returns the address of a bool field in the struct.
+func structPointer_BoolVal(p structPointer, f field) *bool {
+	return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// offset converts from a pointer to a structure to a pointer to
-// one of its fields.
-func (p pointer) offset(f field) pointer {
-	// For safety, we should panic if !f.IsValid, however calling panic causes
-	// this to no longer be inlineable, which is a serious performance cost.
-	/*
-		if !f.IsValid() {
-			panic("invalid field")
-		}
-	*/
-	return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
+// BoolSlice returns the address of a []bool field in the struct.
+func structPointer_BoolSlice(p structPointer, f field) *[]bool {
+	return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-func (p pointer) isNil() bool {
-	return p.p == nil
+// String returns the address of a *string field in the struct.
+func structPointer_String(p structPointer, f field) **string {
+	return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-func (p pointer) toInt64() *int64 {
-	return (*int64)(p.p)
-}
-func (p pointer) toInt64Ptr() **int64 {
-	return (**int64)(p.p)
-}
-func (p pointer) toInt64Slice() *[]int64 {
-	return (*[]int64)(p.p)
-}
-func (p pointer) toInt32() *int32 {
-	return (*int32)(p.p)
+// StringVal returns the address of a string field in the struct.
+func structPointer_StringVal(p structPointer, f field) *string {
+	return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
-/*
-	func (p pointer) toInt32Ptr() **int32 {
-		return (**int32)(p.p)
-	}
-	func (p pointer) toInt32Slice() *[]int32 {
-		return (*[]int32)(p.p)
-	}
-*/
-func (p pointer) getInt32Ptr() *int32 {
-	return *(**int32)(p.p)
-}
-func (p pointer) setInt32Ptr(v int32) {
-	*(**int32)(p.p) = &v
+// StringSlice returns the address of a []string field in the struct.
+func structPointer_StringSlice(p structPointer, f field) *[]string {
+	return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// getInt32Slice loads a []int32 from p.
-// The value returned is aliased with the original slice.
-// This behavior differs from the implementation in pointer_reflect.go.
-func (p pointer) getInt32Slice() []int32 {
-	return *(*[]int32)(p.p)
+// ExtMap returns the address of an extension map field in the struct.
+func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
+	return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// setInt32Slice stores a []int32 to p.
-// The value set is aliased with the input slice.
-// This behavior differs from the implementation in pointer_reflect.go.
-func (p pointer) setInt32Slice(v []int32) {
-	*(*[]int32)(p.p) = v
+func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
+	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
-func (p pointer) appendInt32Slice(v int32) {
-	s := (*[]int32)(p.p)
-	*s = append(*s, v)
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
+	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
 }
 
-func (p pointer) toUint64() *uint64 {
-	return (*uint64)(p.p)
-}
-func (p pointer) toUint64Ptr() **uint64 {
-	return (**uint64)(p.p)
-}
-func (p pointer) toUint64Slice() *[]uint64 {
-	return (*[]uint64)(p.p)
-}
-func (p pointer) toUint32() *uint32 {
-	return (*uint32)(p.p)
-}
-func (p pointer) toUint32Ptr() **uint32 {
-	return (**uint32)(p.p)
-}
-func (p pointer) toUint32Slice() *[]uint32 {
-	return (*[]uint32)(p.p)
-}
-func (p pointer) toBool() *bool {
-	return (*bool)(p.p)
-}
-func (p pointer) toBoolPtr() **bool {
-	return (**bool)(p.p)
-}
-func (p pointer) toBoolSlice() *[]bool {
-	return (*[]bool)(p.p)
-}
-func (p pointer) toFloat64() *float64 {
-	return (*float64)(p.p)
-}
-func (p pointer) toFloat64Ptr() **float64 {
-	return (**float64)(p.p)
-}
-func (p pointer) toFloat64Slice() *[]float64 {
-	return (*[]float64)(p.p)
-}
-func (p pointer) toFloat32() *float32 {
-	return (*float32)(p.p)
+// SetStructPointer writes a *struct field in the struct.
+func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
+	*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
 }
-func (p pointer) toFloat32Ptr() **float32 {
-	return (**float32)(p.p)
-}
-func (p pointer) toFloat32Slice() *[]float32 {
-	return (*[]float32)(p.p)
-}
-func (p pointer) toString() *string {
-	return (*string)(p.p)
-}
-func (p pointer) toStringPtr() **string {
-	return (**string)(p.p)
-}
-func (p pointer) toStringSlice() *[]string {
-	return (*[]string)(p.p)
-}
-func (p pointer) toBytes() *[]byte {
-	return (*[]byte)(p.p)
-}
-func (p pointer) toBytesSlice() *[][]byte {
-	return (*[][]byte)(p.p)
+
+// GetStructPointer reads a *struct field in the struct.
+func structPointer_GetStructPointer(p structPointer, f field) structPointer {
+	return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
-func (p pointer) toExtensions() *XXX_InternalExtensions {
-	return (*XXX_InternalExtensions)(p.p)
+
+// StructPointerSlice the address of a []*struct field in the struct.
+func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
+	return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
-func (p pointer) toOldExtensions() *map[int32]Extension {
-	return (*map[int32]Extension)(p.p)
+
+// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
+type structPointerSlice []structPointer
+
+func (v *structPointerSlice) Len() int                  { return len(*v) }
+func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
+func (v *structPointerSlice) Append(p structPointer)    { *v = append(*v, p) }
+
+// A word32 is the address of a "pointer to 32-bit value" field.
+type word32 **uint32
+
+// IsNil reports whether *v is nil.
+func word32_IsNil(p word32) bool {
+	return *p == nil
 }
 
-// getPointerSlice loads []*T from p as a []pointer.
-// The value returned is aliased with the original slice.
-// This behavior differs from the implementation in pointer_reflect.go.
-func (p pointer) getPointerSlice() []pointer {
-	// Super-tricky - p should point to a []*T where T is a
-	// message type. We load it as []pointer.
-	return *(*[]pointer)(p.p)
+// Set sets *v to point at a newly allocated word set to x.
+func word32_Set(p word32, o *Buffer, x uint32) {
+	if len(o.uint32s) == 0 {
+		o.uint32s = make([]uint32, uint32PoolSize)
+	}
+	o.uint32s[0] = x
+	*p = &o.uint32s[0]
+	o.uint32s = o.uint32s[1:]
 }
 
-// setPointerSlice stores []pointer into p as a []*T.
-// The value set is aliased with the input slice.
-// This behavior differs from the implementation in pointer_reflect.go.
-func (p pointer) setPointerSlice(v []pointer) {
-	// Super-tricky - p should point to a []*T where T is a
-	// message type. We store it as []pointer.
-	*(*[]pointer)(p.p) = v
+// Get gets the value pointed at by *v.
+func word32_Get(p word32) uint32 {
+	return **p
 }
 
-// getPointer loads the pointer at p and returns it.
-func (p pointer) getPointer() pointer {
-	return pointer{p: *(*unsafe.Pointer)(p.p)}
+// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32(p structPointer, f field) word32 {
+	return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
 }
 
-// setPointer stores the pointer q at p.
-func (p pointer) setPointer(q pointer) {
-	*(*unsafe.Pointer)(p.p) = q.p
+// A word32Val is the address of a 32-bit value field.
+type word32Val *uint32
+
+// Set sets *p to x.
+func word32Val_Set(p word32Val, x uint32) {
+	*p = x
 }
 
-// append q to the slice pointed to by p.
-func (p pointer) appendPointer(q pointer) {
-	s := (*[]unsafe.Pointer)(p.p)
-	*s = append(*s, q.p)
+// Get gets the value pointed at by p.
+func word32Val_Get(p word32Val) uint32 {
+	return *p
 }
 
-// getInterfacePointer returns a pointer that points to the
-// interface data of the interface pointed by p.
-func (p pointer) getInterfacePointer() pointer {
-	// Super-tricky - read pointer out of data word of interface value.
-	return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}
+// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32Val(p structPointer, f field) word32Val {
+	return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
 }
 
-// asPointerTo returns a reflect.Value that is a pointer to an
-// object of type t stored at p.
-func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
-	return reflect.NewAt(t, p.p)
+// A word32Slice is a slice of 32-bit values.
+type word32Slice []uint32
+
+func (v *word32Slice) Append(x uint32)    { *v = append(*v, x) }
+func (v *word32Slice) Len() int           { return len(*v) }
+func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
+
+// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
+func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
+	return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
 
-func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
-	return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+// word64 is like word32 but for 64-bit values.
+type word64 **uint64
+
+func word64_Set(p word64, o *Buffer, x uint64) {
+	if len(o.uint64s) == 0 {
+		o.uint64s = make([]uint64, uint64PoolSize)
+	}
+	o.uint64s[0] = x
+	*p = &o.uint64s[0]
+	o.uint64s = o.uint64s[1:]
 }
-func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
-	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+
+func word64_IsNil(p word64) bool {
+	return *p == nil
 }
-func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
-	return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+
+func word64_Get(p word64) uint64 {
+	return **p
 }
-func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
-	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+
+func structPointer_Word64(p structPointer, f field) word64 {
+	return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
 }
-func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
-	return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+
+// word64Val is like word32Val but for 64-bit values.
+type word64Val *uint64
+
+func word64Val_Set(p word64Val, o *Buffer, x uint64) {
+	*p = x
 }
-func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
-	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+
+func word64Val_Get(p word64Val) uint64 {
+	return *p
 }
-func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
-	return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+
+func structPointer_Word64Val(p structPointer, f field) word64Val {
+	return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
 }
-func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
-	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+
+// word64Slice is like word32Slice but for 64-bit values.
+type word64Slice []uint64
+
+func (v *word64Slice) Append(x uint64)    { *v = append(*v, x) }
+func (v *word64Slice) Len() int           { return len(*v) }
+func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
+
+func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
+	return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go
index 50b99b83a..ec2289c00 100644
--- a/vendor/github.com/golang/protobuf/proto/properties.go
+++ b/vendor/github.com/golang/protobuf/proto/properties.go
@@ -58,6 +58,42 @@ const (
 	WireFixed32    = 5
 )
 
+const startSize = 10 // initial slice/string sizes
+
+// Encoders are defined in encode.go
+// An encoder outputs the full representation of a field, including its
+// tag and encoder type.
+type encoder func(p *Buffer, prop *Properties, base structPointer) error
+
+// A valueEncoder encodes a single integer in a particular encoding.
+type valueEncoder func(o *Buffer, x uint64) error
+
+// Sizers are defined in encode.go
+// A sizer returns the encoded size of a field, including its tag and encoder
+// type.
+type sizer func(prop *Properties, base structPointer) int
+
+// A valueSizer returns the encoded size of a single integer in a particular
+// encoding.
+type valueSizer func(x uint64) int
+
+// Decoders are defined in decode.go
+// A decoder creates a value from its wire representation.
+// Unrecognized subelements are saved in unrec.
+type decoder func(p *Buffer, prop *Properties, base structPointer) error
+
+// A valueDecoder decodes a single integer in a particular encoding.
+type valueDecoder func(o *Buffer) (x uint64, err error)
+
+// A oneofMarshaler does the marshaling for all oneof fields in a message.
+type oneofMarshaler func(Message, *Buffer) error
+
+// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
+type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
+
+// A oneofSizer does the sizing for all oneof fields in a message.
+type oneofSizer func(Message) int
+
 // tagMap is an optimization over map[int]int for typical protocol buffer
 // use-cases. Encoded protocol buffers are often in tag order with small tag
 // numbers.
@@ -104,6 +140,13 @@ type StructProperties struct {
 	decoderTags      tagMap         // map from proto tag to struct field number
 	decoderOrigNames map[string]int // map from original name to struct field number
 	order            []int          // list of struct field numbers in tag order
+	unrecField       field          // field id of the XXX_unrecognized []byte field
+	extendable       bool           // is this an extendable proto
+
+	oneofMarshaler   oneofMarshaler
+	oneofUnmarshaler oneofUnmarshaler
+	oneofSizer       oneofSizer
+	stype            reflect.Type
 
 	// OneofTypes contains information about the oneof fields in this message.
 	// It is keyed by the original name of a field.
@@ -139,24 +182,41 @@ type Properties struct {
 	Repeated bool
 	Packed   bool   // relevant for repeated primitives only
 	Enum     string // set for enum types only
-	proto3   bool   // whether this is known to be a proto3 field
+	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
 	oneof    bool   // whether this is a oneof field
 
 	Default    string // default value
 	HasDefault bool   // whether an explicit default was provided
-
-	stype reflect.Type      // set for struct types only
-	sprop *StructProperties // set for struct types only
-
-	mtype      reflect.Type // set for map types only
-	MapKeyProp *Properties  // set for map types only
-	MapValProp *Properties  // set for map types only
+	def_uint64 uint64
+
+	enc           encoder
+	valEnc        valueEncoder // set for bool and numeric types only
+	field         field
+	tagcode       []byte // encoding of EncodeVarint((Tag<<3)|WireType)
+	tagbuf        [8]byte
+	stype         reflect.Type      // set for struct types only
+	sprop         *StructProperties // set for struct types only
+	isMarshaler   bool
+	isUnmarshaler bool
+
+	mtype    reflect.Type // set for map types only
+	mkeyprop *Properties  // set for map types only
+	mvalprop *Properties  // set for map types only
+
+	size    sizer
+	valSize valueSizer // set for bool and numeric types only
+
+	dec    decoder
+	valDec valueDecoder // set for bool and numeric types only
+
+	// If this is a packable field, this will be the decoder for the packed version of the field.
+	packedDec decoder
 }
 
 // String formats the properties in the protobuf struct field tag style.
 func (p *Properties) String() string {
 	s := p.Wire
-	s += ","
+	s = ","
 	s += strconv.Itoa(p.Tag)
 	if p.Required {
 		s += ",req"
@@ -202,14 +262,29 @@ func (p *Properties) Parse(s string) {
 	switch p.Wire {
 	case "varint":
 		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeVarint
+		p.valDec = (*Buffer).DecodeVarint
+		p.valSize = sizeVarint
 	case "fixed32":
 		p.WireType = WireFixed32
+		p.valEnc = (*Buffer).EncodeFixed32
+		p.valDec = (*Buffer).DecodeFixed32
+		p.valSize = sizeFixed32
 	case "fixed64":
 		p.WireType = WireFixed64
+		p.valEnc = (*Buffer).EncodeFixed64
+		p.valDec = (*Buffer).DecodeFixed64
+		p.valSize = sizeFixed64
 	case "zigzag32":
 		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeZigzag32
+		p.valDec = (*Buffer).DecodeZigzag32
+		p.valSize = sizeZigzag32
 	case "zigzag64":
 		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeZigzag64
+		p.valDec = (*Buffer).DecodeZigzag64
+		p.valSize = sizeZigzag64
 	case "bytes", "group":
 		p.WireType = WireBytes
 		// no numeric converter for non-numeric types
@@ -224,7 +299,6 @@ func (p *Properties) Parse(s string) {
 		return
 	}
 
-outer:
 	for i := 2; i < len(fields); i++ {
 		f := fields[i]
 		switch {
@@ -252,41 +326,256 @@ outer:
 			if i+1 < len(fields) {
 				// Commas aren't escaped, and def is always last.
 				p.Default += "," + strings.Join(fields[i+1:], ",")
-				break outer
+				break
 			}
 		}
 	}
 }
 
+func logNoSliceEnc(t1, t2 reflect.Type) {
+	fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
+}
+
 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
 
-// setFieldProps initializes the field properties for submessages and maps.
-func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
+// Initialize the fields for encoding and decoding.
+func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
+	p.enc = nil
+	p.dec = nil
+	p.size = nil
+
 	switch t1 := typ; t1.Kind() {
+	default:
+		fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
+
+	// proto3 scalar types
+
+	case reflect.Bool:
+		p.enc = (*Buffer).enc_proto3_bool
+		p.dec = (*Buffer).dec_proto3_bool
+		p.size = size_proto3_bool
+	case reflect.Int32:
+		p.enc = (*Buffer).enc_proto3_int32
+		p.dec = (*Buffer).dec_proto3_int32
+		p.size = size_proto3_int32
+	case reflect.Uint32:
+		p.enc = (*Buffer).enc_proto3_uint32
+		p.dec = (*Buffer).dec_proto3_int32 // can reuse
+		p.size = size_proto3_uint32
+	case reflect.Int64, reflect.Uint64:
+		p.enc = (*Buffer).enc_proto3_int64
+		p.dec = (*Buffer).dec_proto3_int64
+		p.size = size_proto3_int64
+	case reflect.Float32:
+		p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
+		p.dec = (*Buffer).dec_proto3_int32
+		p.size = size_proto3_uint32
+	case reflect.Float64:
+		p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
+		p.dec = (*Buffer).dec_proto3_int64
+		p.size = size_proto3_int64
+	case reflect.String:
+		p.enc = (*Buffer).enc_proto3_string
+		p.dec = (*Buffer).dec_proto3_string
+		p.size = size_proto3_string
+
 	case reflect.Ptr:
-		if t1.Elem().Kind() == reflect.Struct {
+		switch t2 := t1.Elem(); t2.Kind() {
+		default:
+			fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
+			break
+		case reflect.Bool:
+			p.enc = (*Buffer).enc_bool
+			p.dec = (*Buffer).dec_bool
+			p.size = size_bool
+		case reflect.Int32:
+			p.enc = (*Buffer).enc_int32
+			p.dec = (*Buffer).dec_int32
+			p.size = size_int32
+		case reflect.Uint32:
+			p.enc = (*Buffer).enc_uint32
+			p.dec = (*Buffer).dec_int32 // can reuse
+			p.size = size_uint32
+		case reflect.Int64, reflect.Uint64:
+			p.enc = (*Buffer).enc_int64
+			p.dec = (*Buffer).dec_int64
+			p.size = size_int64
+		case reflect.Float32:
+			p.enc = (*Buffer).enc_uint32 // can just treat them as bits
+			p.dec = (*Buffer).dec_int32
+			p.size = size_uint32
+		case reflect.Float64:
+			p.enc = (*Buffer).enc_int64 // can just treat them as bits
+			p.dec = (*Buffer).dec_int64
+			p.size = size_int64
+		case reflect.String:
+			p.enc = (*Buffer).enc_string
+			p.dec = (*Buffer).dec_string
+			p.size = size_string
+		case reflect.Struct:
 			p.stype = t1.Elem()
+			p.isMarshaler = isMarshaler(t1)
+			p.isUnmarshaler = isUnmarshaler(t1)
+			if p.Wire == "bytes" {
+				p.enc = (*Buffer).enc_struct_message
+				p.dec = (*Buffer).dec_struct_message
+				p.size = size_struct_message
+			} else {
+				p.enc = (*Buffer).enc_struct_group
+				p.dec = (*Buffer).dec_struct_group
+				p.size = size_struct_group
+			}
 		}
 
 	case reflect.Slice:
-		if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct {
-			p.stype = t2.Elem()
+		switch t2 := t1.Elem(); t2.Kind() {
+		default:
+			logNoSliceEnc(t1, t2)
+			break
+		case reflect.Bool:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_bool
+				p.size = size_slice_packed_bool
+			} else {
+				p.enc = (*Buffer).enc_slice_bool
+				p.size = size_slice_bool
+			}
+			p.dec = (*Buffer).dec_slice_bool
+			p.packedDec = (*Buffer).dec_slice_packed_bool
+		case reflect.Int32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_int32
+				p.size = size_slice_packed_int32
+			} else {
+				p.enc = (*Buffer).enc_slice_int32
+				p.size = size_slice_int32
+			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Uint32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_uint32
+				p.size = size_slice_packed_uint32
+			} else {
+				p.enc = (*Buffer).enc_slice_uint32
+				p.size = size_slice_uint32
+			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Int64, reflect.Uint64:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_int64
+				p.size = size_slice_packed_int64
+			} else {
+				p.enc = (*Buffer).enc_slice_int64
+				p.size = size_slice_int64
+			}
+			p.dec = (*Buffer).dec_slice_int64
+			p.packedDec = (*Buffer).dec_slice_packed_int64
+		case reflect.Uint8:
+			p.dec = (*Buffer).dec_slice_byte
+			if p.proto3 {
+				p.enc = (*Buffer).enc_proto3_slice_byte
+				p.size = size_proto3_slice_byte
+			} else {
+				p.enc = (*Buffer).enc_slice_byte
+				p.size = size_slice_byte
+			}
+		case reflect.Float32, reflect.Float64:
+			switch t2.Bits() {
+			case 32:
+				// can just treat them as bits
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_uint32
+					p.size = size_slice_packed_uint32
+				} else {
+					p.enc = (*Buffer).enc_slice_uint32
+					p.size = size_slice_uint32
+				}
+				p.dec = (*Buffer).dec_slice_int32
+				p.packedDec = (*Buffer).dec_slice_packed_int32
+			case 64:
+				// can just treat them as bits
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_int64
+					p.size = size_slice_packed_int64
+				} else {
+					p.enc = (*Buffer).enc_slice_int64
+					p.size = size_slice_int64
+				}
+				p.dec = (*Buffer).dec_slice_int64
+				p.packedDec = (*Buffer).dec_slice_packed_int64
+			default:
+				logNoSliceEnc(t1, t2)
+				break
+			}
+		case reflect.String:
+			p.enc = (*Buffer).enc_slice_string
+			p.dec = (*Buffer).dec_slice_string
+			p.size = size_slice_string
+		case reflect.Ptr:
+			switch t3 := t2.Elem(); t3.Kind() {
+			default:
+				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
+				break
+			case reflect.Struct:
+				p.stype = t2.Elem()
+				p.isMarshaler = isMarshaler(t2)
+				p.isUnmarshaler = isUnmarshaler(t2)
+				if p.Wire == "bytes" {
+					p.enc = (*Buffer).enc_slice_struct_message
+					p.dec = (*Buffer).dec_slice_struct_message
+					p.size = size_slice_struct_message
+				} else {
+					p.enc = (*Buffer).enc_slice_struct_group
+					p.dec = (*Buffer).dec_slice_struct_group
+					p.size = size_slice_struct_group
+				}
+			}
+		case reflect.Slice:
+			switch t2.Elem().Kind() {
+			default:
+				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
+				break
+			case reflect.Uint8:
+				p.enc = (*Buffer).enc_slice_slice_byte
+				p.dec = (*Buffer).dec_slice_slice_byte
+				p.size = size_slice_slice_byte
+			}
 		}
 
 	case reflect.Map:
+		p.enc = (*Buffer).enc_new_map
+		p.dec = (*Buffer).dec_new_map
+		p.size = size_new_map
+
 		p.mtype = t1
-		p.MapKeyProp = &Properties{}
-		p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
-		p.MapValProp = &Properties{}
+		p.mkeyprop = &Properties{}
+		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
+		p.mvalprop = &Properties{}
 		vtype := p.mtype.Elem()
 		if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
 			// The value type is not a message (*T) or bytes ([]byte),
 			// so we need encoders for the pointer to this type.
 			vtype = reflect.PtrTo(vtype)
 		}
-		p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
+		p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
 	}
 
+	// precalculate tag code
+	wire := p.WireType
+	if p.Packed {
+		wire = WireBytes
+	}
+	x := uint32(p.Tag)<<3 | uint32(wire)
+	i := 0
+	for i = 0; x > 127; i++ {
+		p.tagbuf[i] = 0x80 | uint8(x&0x7F)
+		x >>= 7
+	}
+	p.tagbuf[i] = uint8(x)
+	p.tagcode = p.tagbuf[0 : i+1]
+
 	if p.stype != nil {
 		if lockGetProp {
 			p.sprop = GetProperties(p.stype)
@@ -297,9 +586,32 @@ func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, loc
 }
 
 var (
-	marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
+	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
+	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
 )
 
+// isMarshaler reports whether type t implements Marshaler.
+func isMarshaler(t reflect.Type) bool {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isMarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isMarshaler")
+	}
+	return t.Implements(marshalerType)
+}
+
+// isUnmarshaler reports whether type t implements Unmarshaler.
+func isUnmarshaler(t reflect.Type) bool {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isUnmarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isUnmarshaler")
+	}
+	return t.Implements(unmarshalerType)
+}
+
 // Init populates the properties from a protocol buffer struct tag.
 func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
 	p.init(typ, name, tag, f, true)
@@ -309,11 +621,14 @@ func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructF
 	// "bytes,49,opt,def=hello!"
 	p.Name = name
 	p.OrigName = name
+	if f != nil {
+		p.field = toField(f)
+	}
 	if tag == "" {
 		return
 	}
 	p.Parse(tag)
-	p.setFieldProps(typ, f, lockGetProp)
+	p.setEncAndDec(typ, f, lockGetProp)
 }
 
 var (
@@ -363,6 +678,9 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	propertiesMap[t] = prop
 
 	// build properties
+	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
+		reflect.PtrTo(t).Implements(extendableProtoV1Type)
+	prop.unrecField = invalidField
 	prop.Prop = make([]*Properties, t.NumField())
 	prop.order = make([]int, t.NumField())
 
@@ -372,6 +690,17 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 		name := f.Name
 		p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
 
+		if f.Name == "XXX_InternalExtensions" { // special case
+			p.enc = (*Buffer).enc_exts
+			p.dec = nil // not needed
+			p.size = size_exts
+		} else if f.Name == "XXX_extensions" { // special case
+			p.enc = (*Buffer).enc_map
+			p.dec = nil // not needed
+			p.size = size_map
+		} else if f.Name == "XXX_unrecognized" { // special case
+			prop.unrecField = toField(&f)
+		}
 		oneof := f.Tag.Get("protobuf_oneof") // special case
 		if oneof != "" {
 			// Oneof fields don't use the traditional protobuf tag.
@@ -386,6 +715,9 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 			}
 			print("\n")
 		}
+		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
+			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
+		}
 	}
 
 	// Re-order prop.order.
@@ -396,7 +728,8 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	}
 	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
 		var oots []interface{}
-		_, _, _, oots = om.XXX_OneofFuncs()
+		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
+		prop.stype = t
 
 		// Interpret oneof metadata.
 		prop.OneofTypes = make(map[string]*OneofProperties)
@@ -446,6 +779,30 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	return prop
 }
 
+// Return the Properties object for the x[0]'th field of the structure.
+func propByIndex(t reflect.Type, x []int) *Properties {
+	if len(x) != 1 {
+		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
+		return nil
+	}
+	prop := GetProperties(t)
+	return prop.Prop[x[0]]
+}
+
+// Get the address and type of a pointer to a struct from an interface.
+func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
+	if pb == nil {
+		err = ErrNil
+		return
+	}
+	// get the reflect type of the pointer to the struct.
+	t = reflect.TypeOf(pb)
+	// get the address of the struct.
+	value := reflect.ValueOf(pb)
+	b = toStructPointer(value)
+	return
+}
+
 // A global registry of enum types.
 // The generated code will register the generated maps by calling RegisterEnum.
 
@@ -469,42 +826,20 @@ func EnumValueMap(enumType string) map[string]int32 {
 // A registry of all linked message types.
 // The string is a fully-qualified proto name ("pkg.Message").
 var (
-	protoTypedNils = make(map[string]Message)      // a map from proto names to typed nil pointers
-	protoMapTypes  = make(map[string]reflect.Type) // a map from proto names to map types
-	revProtoTypes  = make(map[reflect.Type]string)
+	protoTypes    = make(map[string]reflect.Type)
+	revProtoTypes = make(map[reflect.Type]string)
 )
 
 // RegisterType is called from generated code and maps from the fully qualified
 // proto name to the type (pointer to struct) of the protocol buffer.
 func RegisterType(x Message, name string) {
-	if _, ok := protoTypedNils[name]; ok {
+	if _, ok := protoTypes[name]; ok {
 		// TODO: Some day, make this a panic.
 		log.Printf("proto: duplicate proto type registered: %s", name)
 		return
 	}
 	t := reflect.TypeOf(x)
-	if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
-		// Generated code always calls RegisterType with nil x.
-		// This check is just for extra safety.
-		protoTypedNils[name] = x
-	} else {
-		protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
-	}
-	revProtoTypes[t] = name
-}
-
-// RegisterMapType is called from generated code and maps from the fully qualified
-// proto name to the native map type of the proto map definition.
-func RegisterMapType(x interface{}, name string) {
-	if reflect.TypeOf(x).Kind() != reflect.Map {
-		panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
-	}
-	if _, ok := protoMapTypes[name]; ok {
-		log.Printf("proto: duplicate proto type registered: %s", name)
-		return
-	}
-	t := reflect.TypeOf(x)
-	protoMapTypes[name] = t
+	protoTypes[name] = t
 	revProtoTypes[t] = name
 }
 
@@ -520,14 +855,7 @@ func MessageName(x Message) string {
 }
 
 // MessageType returns the message type (pointer to struct) for a named message.
-// The type is not guaranteed to implement proto.Message if the name refers to a
-// map entry.
-func MessageType(name string) reflect.Type {
-	if t, ok := protoTypedNils[name]; ok {
-		return reflect.TypeOf(t)
-	}
-	return protoMapTypes[name]
-}
+func MessageType(name string) reflect.Type { return protoTypes[name] }
 
 // A registry of all linked proto files.
 var (
diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go
deleted file mode 100644
index b16794496..000000000
--- a/vendor/github.com/golang/protobuf/proto/table_marshal.go
+++ /dev/null
@@ -1,2767 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2016 The Go Authors.  All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-import (
-	"errors"
-	"fmt"
-	"math"
-	"reflect"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"sync/atomic"
-	"unicode/utf8"
-)
-
-// a sizer takes a pointer to a field and the size of its tag, computes the size of
-// the encoded data.
-type sizer func(pointer, int) int
-
-// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),
-// marshals the field to the end of the slice, returns the slice and error (if any).
-type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)
-
-// marshalInfo is the information used for marshaling a message.
-type marshalInfo struct {
-	typ          reflect.Type
-	fields       []*marshalFieldInfo
-	unrecognized field                      // offset of XXX_unrecognized
-	extensions   field                      // offset of XXX_InternalExtensions
-	v1extensions field                      // offset of XXX_extensions
-	sizecache    field                      // offset of XXX_sizecache
-	initialized  int32                      // 0 -- only typ is set, 1 -- fully initialized
-	messageset   bool                       // uses message set wire format
-	hasmarshaler bool                       // has custom marshaler
-	sync.RWMutex                            // protect extElems map, also for initialization
-	extElems     map[int32]*marshalElemInfo // info of extension elements
-}
-
-// marshalFieldInfo is the information used for marshaling a field of a message.
-type marshalFieldInfo struct {
-	field      field
-	wiretag    uint64 // tag in wire format
-	tagsize    int    // size of tag in wire format
-	sizer      sizer
-	marshaler  marshaler
-	isPointer  bool
-	required   bool                              // field is required
-	name       string                            // name of the field, for error reporting
-	oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements
-}
-
-// marshalElemInfo is the information used for marshaling an extension or oneof element.
-type marshalElemInfo struct {
-	wiretag   uint64 // tag in wire format
-	tagsize   int    // size of tag in wire format
-	sizer     sizer
-	marshaler marshaler
-	isptr     bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
-}
-
-var (
-	marshalInfoMap  = map[reflect.Type]*marshalInfo{}
-	marshalInfoLock sync.Mutex
-)
-
-// getMarshalInfo returns the information to marshal a given type of message.
-// The info it returns may not necessarily initialized.
-// t is the type of the message (NOT the pointer to it).
-func getMarshalInfo(t reflect.Type) *marshalInfo {
-	marshalInfoLock.Lock()
-	u, ok := marshalInfoMap[t]
-	if !ok {
-		u = &marshalInfo{typ: t}
-		marshalInfoMap[t] = u
-	}
-	marshalInfoLock.Unlock()
-	return u
-}
-
-// Size is the entry point from generated code,
-// and should be ONLY called by generated code.
-// It computes the size of encoded data of msg.
-// a is a pointer to a place to store cached marshal info.
-func (a *InternalMessageInfo) Size(msg Message) int {
-	u := getMessageMarshalInfo(msg, a)
-	ptr := toPointer(&msg)
-	if ptr.isNil() {
-		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
-		// so it satisfies the interface, and msg == nil wouldn't
-		// catch it. We don't want crash in this case.
-		return 0
-	}
-	return u.size(ptr)
-}
-
-// Marshal is the entry point from generated code,
-// and should be ONLY called by generated code.
-// It marshals msg to the end of b.
-// a is a pointer to a place to store cached marshal info.
-func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) {
-	u := getMessageMarshalInfo(msg, a)
-	ptr := toPointer(&msg)
-	if ptr.isNil() {
-		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
-		// so it satisfies the interface, and msg == nil wouldn't
-		// catch it. We don't want crash in this case.
-		return b, ErrNil
-	}
-	return u.marshal(b, ptr, deterministic)
-}
-
-func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo {
-	// u := a.marshal, but atomically.
-	// We use an atomic here to ensure memory consistency.
-	u := atomicLoadMarshalInfo(&a.marshal)
-	if u == nil {
-		// Get marshal information from type of message.
-		t := reflect.ValueOf(msg).Type()
-		if t.Kind() != reflect.Ptr {
-			panic(fmt.Sprintf("cannot handle non-pointer message type %v", t))
-		}
-		u = getMarshalInfo(t.Elem())
-		// Store it in the cache for later users.
-		// a.marshal = u, but atomically.
-		atomicStoreMarshalInfo(&a.marshal, u)
-	}
-	return u
-}
-
-// size is the main function to compute the size of the encoded data of a message.
-// ptr is the pointer to the message.
-func (u *marshalInfo) size(ptr pointer) int {
-	if atomic.LoadInt32(&u.initialized) == 0 {
-		u.computeMarshalInfo()
-	}
-
-	// If the message can marshal itself, let it do it, for compatibility.
-	// NOTE: This is not efficient.
-	if u.hasmarshaler {
-		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
-		b, _ := m.Marshal()
-		return len(b)
-	}
-
-	n := 0
-	for _, f := range u.fields {
-		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
-			// nil pointer always marshals to nothing
-			continue
-		}
-		n += f.sizer(ptr.offset(f.field), f.tagsize)
-	}
-	if u.extensions.IsValid() {
-		e := ptr.offset(u.extensions).toExtensions()
-		if u.messageset {
-			n += u.sizeMessageSet(e)
-		} else {
-			n += u.sizeExtensions(e)
-		}
-	}
-	if u.v1extensions.IsValid() {
-		m := *ptr.offset(u.v1extensions).toOldExtensions()
-		n += u.sizeV1Extensions(m)
-	}
-	if u.unrecognized.IsValid() {
-		s := *ptr.offset(u.unrecognized).toBytes()
-		n += len(s)
-	}
-	// cache the result for use in marshal
-	if u.sizecache.IsValid() {
-		atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n))
-	}
-	return n
-}
-
-// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),
-// fall back to compute the size.
-func (u *marshalInfo) cachedsize(ptr pointer) int {
-	if u.sizecache.IsValid() {
-		return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32()))
-	}
-	return u.size(ptr)
-}
-
-// marshal is the main function to marshal a message. It takes a byte slice and appends
-// the encoded data to the end of the slice, returns the slice and error (if any).
-// ptr is the pointer to the message.
-// If deterministic is true, map is marshaled in deterministic order.
-func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) {
-	if atomic.LoadInt32(&u.initialized) == 0 {
-		u.computeMarshalInfo()
-	}
-
-	// If the message can marshal itself, let it do it, for compatibility.
-	// NOTE: This is not efficient.
-	if u.hasmarshaler {
-		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
-		b1, err := m.Marshal()
-		b = append(b, b1...)
-		return b, err
-	}
-
-	var err, errLater error
-	// The old marshaler encodes extensions at beginning.
-	if u.extensions.IsValid() {
-		e := ptr.offset(u.extensions).toExtensions()
-		if u.messageset {
-			b, err = u.appendMessageSet(b, e, deterministic)
-		} else {
-			b, err = u.appendExtensions(b, e, deterministic)
-		}
-		if err != nil {
-			return b, err
-		}
-	}
-	if u.v1extensions.IsValid() {
-		m := *ptr.offset(u.v1extensions).toOldExtensions()
-		b, err = u.appendV1Extensions(b, m, deterministic)
-		if err != nil {
-			return b, err
-		}
-	}
-	for _, f := range u.fields {
-		if f.required {
-			if ptr.offset(f.field).getPointer().isNil() {
-				// Required field is not set.
-				// We record the error but keep going, to give a complete marshaling.
-				if errLater == nil {
-					errLater = &RequiredNotSetError{f.name}
-				}
-				continue
-			}
-		}
-		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
-			// nil pointer always marshals to nothing
-			continue
-		}
-		b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic)
-		if err != nil {
-			if err1, ok := err.(*RequiredNotSetError); ok {
-				// Required field in submessage is not set.
-				// We record the error but keep going, to give a complete marshaling.
-				if errLater == nil {
-					errLater = &RequiredNotSetError{f.name + "." + err1.field}
-				}
-				continue
-			}
-			if err == errRepeatedHasNil {
-				err = errors.New("proto: repeated field " + f.name + " has nil element")
-			}
-			if err == errInvalidUTF8 {
-				if errLater == nil {
-					fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
-					errLater = &invalidUTF8Error{fullName}
-				}
-				continue
-			}
-			return b, err
-		}
-	}
-	if u.unrecognized.IsValid() {
-		s := *ptr.offset(u.unrecognized).toBytes()
-		b = append(b, s...)
-	}
-	return b, errLater
-}
-
-// computeMarshalInfo initializes the marshal info.
-func (u *marshalInfo) computeMarshalInfo() {
-	u.Lock()
-	defer u.Unlock()
-	if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock
-		return
-	}
-
-	t := u.typ
-	u.unrecognized = invalidField
-	u.extensions = invalidField
-	u.v1extensions = invalidField
-	u.sizecache = invalidField
-
-	// If the message can marshal itself, let it do it, for compatibility.
-	// NOTE: This is not efficient.
-	if reflect.PtrTo(t).Implements(marshalerType) {
-		u.hasmarshaler = true
-		atomic.StoreInt32(&u.initialized, 1)
-		return
-	}
-
-	// get oneof implementers
-	var oneofImplementers []interface{}
-	if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
-		_, _, _, oneofImplementers = m.XXX_OneofFuncs()
-	}
-
-	n := t.NumField()
-
-	// deal with XXX fields first
-	for i := 0; i < t.NumField(); i++ {
-		f := t.Field(i)
-		if !strings.HasPrefix(f.Name, "XXX_") {
-			continue
-		}
-		switch f.Name {
-		case "XXX_sizecache":
-			u.sizecache = toField(&f)
-		case "XXX_unrecognized":
-			u.unrecognized = toField(&f)
-		case "XXX_InternalExtensions":
-			u.extensions = toField(&f)
-			u.messageset = f.Tag.Get("protobuf_messageset") == "1"
-		case "XXX_extensions":
-			u.v1extensions = toField(&f)
-		case "XXX_NoUnkeyedLiteral":
-			// nothing to do
-		default:
-			panic("unknown XXX field: " + f.Name)
-		}
-		n--
-	}
-
-	// normal fields
-	fields := make([]marshalFieldInfo, n) // batch allocation
-	u.fields = make([]*marshalFieldInfo, 0, n)
-	for i, j := 0, 0; i < t.NumField(); i++ {
-		f := t.Field(i)
-
-		if strings.HasPrefix(f.Name, "XXX_") {
-			continue
-		}
-		field := &fields[j]
-		j++
-		field.name = f.Name
-		u.fields = append(u.fields, field)
-		if f.Tag.Get("protobuf_oneof") != "" {
-			field.computeOneofFieldInfo(&f, oneofImplementers)
-			continue
-		}
-		if f.Tag.Get("protobuf") == "" {
-			// field has no tag (not in generated message), ignore it
-			u.fields = u.fields[:len(u.fields)-1]
-			j--
-			continue
-		}
-		field.computeMarshalFieldInfo(&f)
-	}
-
-	// fields are marshaled in tag order on the wire.
-	sort.Sort(byTag(u.fields))
-
-	atomic.StoreInt32(&u.initialized, 1)
-}
-
-// helper for sorting fields by tag
-type byTag []*marshalFieldInfo
-
-func (a byTag) Len() int           { return len(a) }
-func (a byTag) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag }
-
-// getExtElemInfo returns the information to marshal an extension element.
-// The info it returns is initialized.
-func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
-	// get from cache first
-	u.RLock()
-	e, ok := u.extElems[desc.Field]
-	u.RUnlock()
-	if ok {
-		return e
-	}
-
-	t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct
-	tags := strings.Split(desc.Tag, ",")
-	tag, err := strconv.Atoi(tags[1])
-	if err != nil {
-		panic("tag is not an integer")
-	}
-	wt := wiretype(tags[0])
-	sizer, marshaler := typeMarshaler(t, tags, false, false)
-	e = &marshalElemInfo{
-		wiretag:   uint64(tag)<<3 | wt,
-		tagsize:   SizeVarint(uint64(tag) << 3),
-		sizer:     sizer,
-		marshaler: marshaler,
-		isptr:     t.Kind() == reflect.Ptr,
-	}
-
-	// update cache
-	u.Lock()
-	if u.extElems == nil {
-		u.extElems = make(map[int32]*marshalElemInfo)
-	}
-	u.extElems[desc.Field] = e
-	u.Unlock()
-	return e
-}
-
-// computeMarshalFieldInfo fills up the information to marshal a field.
-func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
-	// parse protobuf tag of the field.
-	// tag has format of "bytes,49,opt,name=foo,def=hello!"
-	tags := strings.Split(f.Tag.Get("protobuf"), ",")
-	if tags[0] == "" {
-		return
-	}
-	tag, err := strconv.Atoi(tags[1])
-	if err != nil {
-		panic("tag is not an integer")
-	}
-	wt := wiretype(tags[0])
-	if tags[2] == "req" {
-		fi.required = true
-	}
-	fi.setTag(f, tag, wt)
-	fi.setMarshaler(f, tags)
-}
-
-func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
-	fi.field = toField(f)
-	fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
-	fi.isPointer = true
-	fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
-	fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
-
-	ityp := f.Type // interface type
-	for _, o := range oneofImplementers {
-		t := reflect.TypeOf(o)
-		if !t.Implements(ityp) {
-			continue
-		}
-		sf := t.Elem().Field(0) // oneof implementer is a struct with a single field
-		tags := strings.Split(sf.Tag.Get("protobuf"), ",")
-		tag, err := strconv.Atoi(tags[1])
-		if err != nil {
-			panic("tag is not an integer")
-		}
-		wt := wiretype(tags[0])
-		sizer, marshaler := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value
-		fi.oneofElems[t.Elem()] = &marshalElemInfo{
-			wiretag:   uint64(tag)<<3 | wt,
-			tagsize:   SizeVarint(uint64(tag) << 3),
-			sizer:     sizer,
-			marshaler: marshaler,
-		}
-	}
-}
-
-type oneofMessage interface {
-	XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
-}
-
-// wiretype returns the wire encoding of the type.
-func wiretype(encoding string) uint64 {
-	switch encoding {
-	case "fixed32":
-		return WireFixed32
-	case "fixed64":
-		return WireFixed64
-	case "varint", "zigzag32", "zigzag64":
-		return WireVarint
-	case "bytes":
-		return WireBytes
-	case "group":
-		return WireStartGroup
-	}
-	panic("unknown wire type " + encoding)
-}
-
-// setTag fills up the tag (in wire format) and its size in the info of a field.
-func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) {
-	fi.field = toField(f)
-	fi.wiretag = uint64(tag)<<3 | wt
-	fi.tagsize = SizeVarint(uint64(tag) << 3)
-}
-
-// setMarshaler fills up the sizer and marshaler in the info of a field.
-func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) {
-	switch f.Type.Kind() {
-	case reflect.Map:
-		// map field
-		fi.isPointer = true
-		fi.sizer, fi.marshaler = makeMapMarshaler(f)
-		return
-	case reflect.Ptr, reflect.Slice:
-		fi.isPointer = true
-	}
-	fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false)
-}
-
-// typeMarshaler returns the sizer and marshaler of a given field.
-// t is the type of the field.
-// tags is the generated "protobuf" tag of the field.
-// If nozero is true, zero value is not marshaled to the wire.
-// If oneof is true, it is a oneof field.
-func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) {
-	encoding := tags[0]
-
-	pointer := false
-	slice := false
-	if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
-		slice = true
-		t = t.Elem()
-	}
-	if t.Kind() == reflect.Ptr {
-		pointer = true
-		t = t.Elem()
-	}
-
-	packed := false
-	proto3 := false
-	validateUTF8 := true
-	for i := 2; i < len(tags); i++ {
-		if tags[i] == "packed" {
-			packed = true
-		}
-		if tags[i] == "proto3" {
-			proto3 = true
-		}
-	}
-	validateUTF8 = validateUTF8 && proto3
-
-	switch t.Kind() {
-	case reflect.Bool:
-		if pointer {
-			return sizeBoolPtr, appendBoolPtr
-		}
-		if slice {
-			if packed {
-				return sizeBoolPackedSlice, appendBoolPackedSlice
-			}
-			return sizeBoolSlice, appendBoolSlice
-		}
-		if nozero {
-			return sizeBoolValueNoZero, appendBoolValueNoZero
-		}
-		return sizeBoolValue, appendBoolValue
-	case reflect.Uint32:
-		switch encoding {
-		case "fixed32":
-			if pointer {
-				return sizeFixed32Ptr, appendFixed32Ptr
-			}
-			if slice {
-				if packed {
-					return sizeFixed32PackedSlice, appendFixed32PackedSlice
-				}
-				return sizeFixed32Slice, appendFixed32Slice
-			}
-			if nozero {
-				return sizeFixed32ValueNoZero, appendFixed32ValueNoZero
-			}
-			return sizeFixed32Value, appendFixed32Value
-		case "varint":
-			if pointer {
-				return sizeVarint32Ptr, appendVarint32Ptr
-			}
-			if slice {
-				if packed {
-					return sizeVarint32PackedSlice, appendVarint32PackedSlice
-				}
-				return sizeVarint32Slice, appendVarint32Slice
-			}
-			if nozero {
-				return sizeVarint32ValueNoZero, appendVarint32ValueNoZero
-			}
-			return sizeVarint32Value, appendVarint32Value
-		}
-	case reflect.Int32:
-		switch encoding {
-		case "fixed32":
-			if pointer {
-				return sizeFixedS32Ptr, appendFixedS32Ptr
-			}
-			if slice {
-				if packed {
-					return sizeFixedS32PackedSlice, appendFixedS32PackedSlice
-				}
-				return sizeFixedS32Slice, appendFixedS32Slice
-			}
-			if nozero {
-				return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero
-			}
-			return sizeFixedS32Value, appendFixedS32Value
-		case "varint":
-			if pointer {
-				return sizeVarintS32Ptr, appendVarintS32Ptr
-			}
-			if slice {
-				if packed {
-					return sizeVarintS32PackedSlice, appendVarintS32PackedSlice
-				}
-				return sizeVarintS32Slice, appendVarintS32Slice
-			}
-			if nozero {
-				return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero
-			}
-			return sizeVarintS32Value, appendVarintS32Value
-		case "zigzag32":
-			if pointer {
-				return sizeZigzag32Ptr, appendZigzag32Ptr
-			}
-			if slice {
-				if packed {
-					return sizeZigzag32PackedSlice, appendZigzag32PackedSlice
-				}
-				return sizeZigzag32Slice, appendZigzag32Slice
-			}
-			if nozero {
-				return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero
-			}
-			return sizeZigzag32Value, appendZigzag32Value
-		}
-	case reflect.Uint64:
-		switch encoding {
-		case "fixed64":
-			if pointer {
-				return sizeFixed64Ptr, appendFixed64Ptr
-			}
-			if slice {
-				if packed {
-					return sizeFixed64PackedSlice, appendFixed64PackedSlice
-				}
-				return sizeFixed64Slice, appendFixed64Slice
-			}
-			if nozero {
-				return sizeFixed64ValueNoZero, appendFixed64ValueNoZero
-			}
-			return sizeFixed64Value, appendFixed64Value
-		case "varint":
-			if pointer {
-				return sizeVarint64Ptr, appendVarint64Ptr
-			}
-			if slice {
-				if packed {
-					return sizeVarint64PackedSlice, appendVarint64PackedSlice
-				}
-				return sizeVarint64Slice, appendVarint64Slice
-			}
-			if nozero {
-				return sizeVarint64ValueNoZero, appendVarint64ValueNoZero
-			}
-			return sizeVarint64Value, appendVarint64Value
-		}
-	case reflect.Int64:
-		switch encoding {
-		case "fixed64":
-			if pointer {
-				return sizeFixedS64Ptr, appendFixedS64Ptr
-			}
-			if slice {
-				if packed {
-					return sizeFixedS64PackedSlice, appendFixedS64PackedSlice
-				}
-				return sizeFixedS64Slice, appendFixedS64Slice
-			}
-			if nozero {
-				return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero
-			}
-			return sizeFixedS64Value, appendFixedS64Value
-		case "varint":
-			if pointer {
-				return sizeVarintS64Ptr, appendVarintS64Ptr
-			}
-			if slice {
-				if packed {
-					return sizeVarintS64PackedSlice, appendVarintS64PackedSlice
-				}
-				return sizeVarintS64Slice, appendVarintS64Slice
-			}
-			if nozero {
-				return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero
-			}
-			return sizeVarintS64Value, appendVarintS64Value
-		case "zigzag64":
-			if pointer {
-				return sizeZigzag64Ptr, appendZigzag64Ptr
-			}
-			if slice {
-				if packed {
-					return sizeZigzag64PackedSlice, appendZigzag64PackedSlice
-				}
-				return sizeZigzag64Slice, appendZigzag64Slice
-			}
-			if nozero {
-				return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero
-			}
-			return sizeZigzag64Value, appendZigzag64Value
-		}
-	case reflect.Float32:
-		if pointer {
-			return sizeFloat32Ptr, appendFloat32Ptr
-		}
-		if slice {
-			if packed {
-				return sizeFloat32PackedSlice, appendFloat32PackedSlice
-			}
-			return sizeFloat32Slice, appendFloat32Slice
-		}
-		if nozero {
-			return sizeFloat32ValueNoZero, appendFloat32ValueNoZero
-		}
-		return sizeFloat32Value, appendFloat32Value
-	case reflect.Float64:
-		if pointer {
-			return sizeFloat64Ptr, appendFloat64Ptr
-		}
-		if slice {
-			if packed {
-				return sizeFloat64PackedSlice, appendFloat64PackedSlice
-			}
-			return sizeFloat64Slice, appendFloat64Slice
-		}
-		if nozero {
-			return sizeFloat64ValueNoZero, appendFloat64ValueNoZero
-		}
-		return sizeFloat64Value, appendFloat64Value
-	case reflect.String:
-		if validateUTF8 {
-			if pointer {
-				return sizeStringPtr, appendUTF8StringPtr
-			}
-			if slice {
-				return sizeStringSlice, appendUTF8StringSlice
-			}
-			if nozero {
-				return sizeStringValueNoZero, appendUTF8StringValueNoZero
-			}
-			return sizeStringValue, appendUTF8StringValue
-		}
-		if pointer {
-			return sizeStringPtr, appendStringPtr
-		}
-		if slice {
-			return sizeStringSlice, appendStringSlice
-		}
-		if nozero {
-			return sizeStringValueNoZero, appendStringValueNoZero
-		}
-		return sizeStringValue, appendStringValue
-	case reflect.Slice:
-		if slice {
-			return sizeBytesSlice, appendBytesSlice
-		}
-		if oneof {
-			// Oneof bytes field may also have "proto3" tag.
-			// We want to marshal it as a oneof field. Do this
-			// check before the proto3 check.
-			return sizeBytesOneof, appendBytesOneof
-		}
-		if proto3 {
-			return sizeBytes3, appendBytes3
-		}
-		return sizeBytes, appendBytes
-	case reflect.Struct:
-		switch encoding {
-		case "group":
-			if slice {
-				return makeGroupSliceMarshaler(getMarshalInfo(t))
-			}
-			return makeGroupMarshaler(getMarshalInfo(t))
-		case "bytes":
-			if slice {
-				return makeMessageSliceMarshaler(getMarshalInfo(t))
-			}
-			return makeMessageMarshaler(getMarshalInfo(t))
-		}
-	}
-	panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding))
-}
-
-// Below are functions to size/marshal a specific type of a field.
-// They are stored in the field's info, and called by function pointers.
-// They have type sizer or marshaler.
-
-func sizeFixed32Value(_ pointer, tagsize int) int {
-	return 4 + tagsize
-}
-func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toUint32()
-	if v == 0 {
-		return 0
-	}
-	return 4 + tagsize
-}
-func sizeFixed32Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toUint32Ptr()
-	if p == nil {
-		return 0
-	}
-	return 4 + tagsize
-}
-func sizeFixed32Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint32Slice()
-	return (4 + tagsize) * len(s)
-}
-func sizeFixed32PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint32Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
-}
-func sizeFixedS32Value(_ pointer, tagsize int) int {
-	return 4 + tagsize
-}
-func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toInt32()
-	if v == 0 {
-		return 0
-	}
-	return 4 + tagsize
-}
-func sizeFixedS32Ptr(ptr pointer, tagsize int) int {
-	p := ptr.getInt32Ptr()
-	if p == nil {
-		return 0
-	}
-	return 4 + tagsize
-}
-func sizeFixedS32Slice(ptr pointer, tagsize int) int {
-	s := ptr.getInt32Slice()
-	return (4 + tagsize) * len(s)
-}
-func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int {
-	s := ptr.getInt32Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
-}
-func sizeFloat32Value(_ pointer, tagsize int) int {
-	return 4 + tagsize
-}
-func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int {
-	v := math.Float32bits(*ptr.toFloat32())
-	if v == 0 {
-		return 0
-	}
-	return 4 + tagsize
-}
-func sizeFloat32Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toFloat32Ptr()
-	if p == nil {
-		return 0
-	}
-	return 4 + tagsize
-}
-func sizeFloat32Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toFloat32Slice()
-	return (4 + tagsize) * len(s)
-}
-func sizeFloat32PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toFloat32Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
-}
-func sizeFixed64Value(_ pointer, tagsize int) int {
-	return 8 + tagsize
-}
-func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toUint64()
-	if v == 0 {
-		return 0
-	}
-	return 8 + tagsize
-}
-func sizeFixed64Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toUint64Ptr()
-	if p == nil {
-		return 0
-	}
-	return 8 + tagsize
-}
-func sizeFixed64Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint64Slice()
-	return (8 + tagsize) * len(s)
-}
-func sizeFixed64PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint64Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
-}
-func sizeFixedS64Value(_ pointer, tagsize int) int {
-	return 8 + tagsize
-}
-func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toInt64()
-	if v == 0 {
-		return 0
-	}
-	return 8 + tagsize
-}
-func sizeFixedS64Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toInt64Ptr()
-	if p == nil {
-		return 0
-	}
-	return 8 + tagsize
-}
-func sizeFixedS64Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toInt64Slice()
-	return (8 + tagsize) * len(s)
-}
-func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toInt64Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
-}
-func sizeFloat64Value(_ pointer, tagsize int) int {
-	return 8 + tagsize
-}
-func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int {
-	v := math.Float64bits(*ptr.toFloat64())
-	if v == 0 {
-		return 0
-	}
-	return 8 + tagsize
-}
-func sizeFloat64Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toFloat64Ptr()
-	if p == nil {
-		return 0
-	}
-	return 8 + tagsize
-}
-func sizeFloat64Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toFloat64Slice()
-	return (8 + tagsize) * len(s)
-}
-func sizeFloat64PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toFloat64Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
-}
-func sizeVarint32Value(ptr pointer, tagsize int) int {
-	v := *ptr.toUint32()
-	return SizeVarint(uint64(v)) + tagsize
-}
-func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toUint32()
-	if v == 0 {
-		return 0
-	}
-	return SizeVarint(uint64(v)) + tagsize
-}
-func sizeVarint32Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toUint32Ptr()
-	if p == nil {
-		return 0
-	}
-	return SizeVarint(uint64(*p)) + tagsize
-}
-func sizeVarint32Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint32Slice()
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v)) + tagsize
-	}
-	return n
-}
-func sizeVarint32PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint32Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v))
-	}
-	return n + SizeVarint(uint64(n)) + tagsize
-}
-func sizeVarintS32Value(ptr pointer, tagsize int) int {
-	v := *ptr.toInt32()
-	return SizeVarint(uint64(v)) + tagsize
-}
-func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toInt32()
-	if v == 0 {
-		return 0
-	}
-	return SizeVarint(uint64(v)) + tagsize
-}
-func sizeVarintS32Ptr(ptr pointer, tagsize int) int {
-	p := ptr.getInt32Ptr()
-	if p == nil {
-		return 0
-	}
-	return SizeVarint(uint64(*p)) + tagsize
-}
-func sizeVarintS32Slice(ptr pointer, tagsize int) int {
-	s := ptr.getInt32Slice()
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v)) + tagsize
-	}
-	return n
-}
-func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int {
-	s := ptr.getInt32Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v))
-	}
-	return n + SizeVarint(uint64(n)) + tagsize
-}
-func sizeVarint64Value(ptr pointer, tagsize int) int {
-	v := *ptr.toUint64()
-	return SizeVarint(v) + tagsize
-}
-func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toUint64()
-	if v == 0 {
-		return 0
-	}
-	return SizeVarint(v) + tagsize
-}
-func sizeVarint64Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toUint64Ptr()
-	if p == nil {
-		return 0
-	}
-	return SizeVarint(*p) + tagsize
-}
-func sizeVarint64Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint64Slice()
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(v) + tagsize
-	}
-	return n
-}
-func sizeVarint64PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toUint64Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(v)
-	}
-	return n + SizeVarint(uint64(n)) + tagsize
-}
-func sizeVarintS64Value(ptr pointer, tagsize int) int {
-	v := *ptr.toInt64()
-	return SizeVarint(uint64(v)) + tagsize
-}
-func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toInt64()
-	if v == 0 {
-		return 0
-	}
-	return SizeVarint(uint64(v)) + tagsize
-}
-func sizeVarintS64Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toInt64Ptr()
-	if p == nil {
-		return 0
-	}
-	return SizeVarint(uint64(*p)) + tagsize
-}
-func sizeVarintS64Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toInt64Slice()
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v)) + tagsize
-	}
-	return n
-}
-func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toInt64Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v))
-	}
-	return n + SizeVarint(uint64(n)) + tagsize
-}
-func sizeZigzag32Value(ptr pointer, tagsize int) int {
-	v := *ptr.toInt32()
-	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
-}
-func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toInt32()
-	if v == 0 {
-		return 0
-	}
-	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
-}
-func sizeZigzag32Ptr(ptr pointer, tagsize int) int {
-	p := ptr.getInt32Ptr()
-	if p == nil {
-		return 0
-	}
-	v := *p
-	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
-}
-func sizeZigzag32Slice(ptr pointer, tagsize int) int {
-	s := ptr.getInt32Slice()
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
-	}
-	return n
-}
-func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int {
-	s := ptr.getInt32Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
-	}
-	return n + SizeVarint(uint64(n)) + tagsize
-}
-func sizeZigzag64Value(ptr pointer, tagsize int) int {
-	v := *ptr.toInt64()
-	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
-}
-func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toInt64()
-	if v == 0 {
-		return 0
-	}
-	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
-}
-func sizeZigzag64Ptr(ptr pointer, tagsize int) int {
-	p := *ptr.toInt64Ptr()
-	if p == nil {
-		return 0
-	}
-	v := *p
-	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
-}
-func sizeZigzag64Slice(ptr pointer, tagsize int) int {
-	s := *ptr.toInt64Slice()
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
-	}
-	return n
-}
-func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toInt64Slice()
-	if len(s) == 0 {
-		return 0
-	}
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
-	}
-	return n + SizeVarint(uint64(n)) + tagsize
-}
-func sizeBoolValue(_ pointer, tagsize int) int {
-	return 1 + tagsize
-}
-func sizeBoolValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toBool()
-	if !v {
-		return 0
-	}
-	return 1 + tagsize
-}
-func sizeBoolPtr(ptr pointer, tagsize int) int {
-	p := *ptr.toBoolPtr()
-	if p == nil {
-		return 0
-	}
-	return 1 + tagsize
-}
-func sizeBoolSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toBoolSlice()
-	return (1 + tagsize) * len(s)
-}
-func sizeBoolPackedSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toBoolSlice()
-	if len(s) == 0 {
-		return 0
-	}
-	return len(s) + SizeVarint(uint64(len(s))) + tagsize
-}
-func sizeStringValue(ptr pointer, tagsize int) int {
-	v := *ptr.toString()
-	return len(v) + SizeVarint(uint64(len(v))) + tagsize
-}
-func sizeStringValueNoZero(ptr pointer, tagsize int) int {
-	v := *ptr.toString()
-	if v == "" {
-		return 0
-	}
-	return len(v) + SizeVarint(uint64(len(v))) + tagsize
-}
-func sizeStringPtr(ptr pointer, tagsize int) int {
-	p := *ptr.toStringPtr()
-	if p == nil {
-		return 0
-	}
-	v := *p
-	return len(v) + SizeVarint(uint64(len(v))) + tagsize
-}
-func sizeStringSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toStringSlice()
-	n := 0
-	for _, v := range s {
-		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
-	}
-	return n
-}
-func sizeBytes(ptr pointer, tagsize int) int {
-	v := *ptr.toBytes()
-	if v == nil {
-		return 0
-	}
-	return len(v) + SizeVarint(uint64(len(v))) + tagsize
-}
-func sizeBytes3(ptr pointer, tagsize int) int {
-	v := *ptr.toBytes()
-	if len(v) == 0 {
-		return 0
-	}
-	return len(v) + SizeVarint(uint64(len(v))) + tagsize
-}
-func sizeBytesOneof(ptr pointer, tagsize int) int {
-	v := *ptr.toBytes()
-	return len(v) + SizeVarint(uint64(len(v))) + tagsize
-}
-func sizeBytesSlice(ptr pointer, tagsize int) int {
-	s := *ptr.toBytesSlice()
-	n := 0
-	for _, v := range s {
-		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
-	}
-	return n
-}
-
-// appendFixed32 appends an encoded fixed32 to b.
-func appendFixed32(b []byte, v uint32) []byte {
-	b = append(b,
-		byte(v),
-		byte(v>>8),
-		byte(v>>16),
-		byte(v>>24))
-	return b
-}
-
-// appendFixed64 appends an encoded fixed64 to b.
-func appendFixed64(b []byte, v uint64) []byte {
-	b = append(b,
-		byte(v),
-		byte(v>>8),
-		byte(v>>16),
-		byte(v>>24),
-		byte(v>>32),
-		byte(v>>40),
-		byte(v>>48),
-		byte(v>>56))
-	return b
-}
-
-// appendVarint appends an encoded varint to b.
-func appendVarint(b []byte, v uint64) []byte {
-	// TODO: make 1-byte (maybe 2-byte) case inline-able, once we
-	// have non-leaf inliner.
-	switch {
-	case v < 1<<7:
-		b = append(b, byte(v))
-	case v < 1<<14:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte(v>>7))
-	case v < 1<<21:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte(v>>14))
-	case v < 1<<28:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte((v>>14)&0x7f|0x80),
-			byte(v>>21))
-	case v < 1<<35:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte((v>>14)&0x7f|0x80),
-			byte((v>>21)&0x7f|0x80),
-			byte(v>>28))
-	case v < 1<<42:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte((v>>14)&0x7f|0x80),
-			byte((v>>21)&0x7f|0x80),
-			byte((v>>28)&0x7f|0x80),
-			byte(v>>35))
-	case v < 1<<49:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte((v>>14)&0x7f|0x80),
-			byte((v>>21)&0x7f|0x80),
-			byte((v>>28)&0x7f|0x80),
-			byte((v>>35)&0x7f|0x80),
-			byte(v>>42))
-	case v < 1<<56:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte((v>>14)&0x7f|0x80),
-			byte((v>>21)&0x7f|0x80),
-			byte((v>>28)&0x7f|0x80),
-			byte((v>>35)&0x7f|0x80),
-			byte((v>>42)&0x7f|0x80),
-			byte(v>>49))
-	case v < 1<<63:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte((v>>14)&0x7f|0x80),
-			byte((v>>21)&0x7f|0x80),
-			byte((v>>28)&0x7f|0x80),
-			byte((v>>35)&0x7f|0x80),
-			byte((v>>42)&0x7f|0x80),
-			byte((v>>49)&0x7f|0x80),
-			byte(v>>56))
-	default:
-		b = append(b,
-			byte(v&0x7f|0x80),
-			byte((v>>7)&0x7f|0x80),
-			byte((v>>14)&0x7f|0x80),
-			byte((v>>21)&0x7f|0x80),
-			byte((v>>28)&0x7f|0x80),
-			byte((v>>35)&0x7f|0x80),
-			byte((v>>42)&0x7f|0x80),
-			byte((v>>49)&0x7f|0x80),
-			byte((v>>56)&0x7f|0x80),
-			1)
-	}
-	return b
-}
-
-func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint32()
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, v)
-	return b, nil
-}
-func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint32()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, v)
-	return b, nil
-}
-func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toUint32Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, *p)
-	return b, nil
-}
-func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint32Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendFixed32(b, v)
-	}
-	return b, nil
-}
-func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint32Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	b = appendVarint(b, uint64(4*len(s)))
-	for _, v := range s {
-		b = appendFixed32(b, v)
-	}
-	return b, nil
-}
-func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt32()
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, uint32(v))
-	return b, nil
-}
-func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt32()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, uint32(v))
-	return b, nil
-}
-func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := ptr.getInt32Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, uint32(*p))
-	return b, nil
-}
-func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := ptr.getInt32Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendFixed32(b, uint32(v))
-	}
-	return b, nil
-}
-func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := ptr.getInt32Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	b = appendVarint(b, uint64(4*len(s)))
-	for _, v := range s {
-		b = appendFixed32(b, uint32(v))
-	}
-	return b, nil
-}
-func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := math.Float32bits(*ptr.toFloat32())
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, v)
-	return b, nil
-}
-func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := math.Float32bits(*ptr.toFloat32())
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, v)
-	return b, nil
-}
-func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toFloat32Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed32(b, math.Float32bits(*p))
-	return b, nil
-}
-func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toFloat32Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendFixed32(b, math.Float32bits(v))
-	}
-	return b, nil
-}
-func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toFloat32Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	b = appendVarint(b, uint64(4*len(s)))
-	for _, v := range s {
-		b = appendFixed32(b, math.Float32bits(v))
-	}
-	return b, nil
-}
-func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint64()
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, v)
-	return b, nil
-}
-func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint64()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, v)
-	return b, nil
-}
-func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toUint64Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, *p)
-	return b, nil
-}
-func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint64Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendFixed64(b, v)
-	}
-	return b, nil
-}
-func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint64Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	b = appendVarint(b, uint64(8*len(s)))
-	for _, v := range s {
-		b = appendFixed64(b, v)
-	}
-	return b, nil
-}
-func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt64()
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, uint64(v))
-	return b, nil
-}
-func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt64()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, uint64(v))
-	return b, nil
-}
-func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toInt64Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, uint64(*p))
-	return b, nil
-}
-func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toInt64Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendFixed64(b, uint64(v))
-	}
-	return b, nil
-}
-func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toInt64Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	b = appendVarint(b, uint64(8*len(s)))
-	for _, v := range s {
-		b = appendFixed64(b, uint64(v))
-	}
-	return b, nil
-}
-func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := math.Float64bits(*ptr.toFloat64())
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, v)
-	return b, nil
-}
-func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := math.Float64bits(*ptr.toFloat64())
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, v)
-	return b, nil
-}
-func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toFloat64Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendFixed64(b, math.Float64bits(*p))
-	return b, nil
-}
-func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toFloat64Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendFixed64(b, math.Float64bits(v))
-	}
-	return b, nil
-}
-func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toFloat64Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	b = appendVarint(b, uint64(8*len(s)))
-	for _, v := range s {
-		b = appendFixed64(b, math.Float64bits(v))
-	}
-	return b, nil
-}
-func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint32()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v))
-	return b, nil
-}
-func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint32()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v))
-	return b, nil
-}
-func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toUint32Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(*p))
-	return b, nil
-}
-func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint32Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64(v))
-	}
-	return b, nil
-}
-func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint32Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	// compute size
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v))
-	}
-	b = appendVarint(b, uint64(n))
-	for _, v := range s {
-		b = appendVarint(b, uint64(v))
-	}
-	return b, nil
-}
-func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt32()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v))
-	return b, nil
-}
-func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt32()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v))
-	return b, nil
-}
-func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := ptr.getInt32Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(*p))
-	return b, nil
-}
-func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := ptr.getInt32Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64(v))
-	}
-	return b, nil
-}
-func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := ptr.getInt32Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	// compute size
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v))
-	}
-	b = appendVarint(b, uint64(n))
-	for _, v := range s {
-		b = appendVarint(b, uint64(v))
-	}
-	return b, nil
-}
-func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint64()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, v)
-	return b, nil
-}
-func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toUint64()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, v)
-	return b, nil
-}
-func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toUint64Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, *p)
-	return b, nil
-}
-func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint64Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, v)
-	}
-	return b, nil
-}
-func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toUint64Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	// compute size
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(v)
-	}
-	b = appendVarint(b, uint64(n))
-	for _, v := range s {
-		b = appendVarint(b, v)
-	}
-	return b, nil
-}
-func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt64()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v))
-	return b, nil
-}
-func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt64()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v))
-	return b, nil
-}
-func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toInt64Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(*p))
-	return b, nil
-}
-func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toInt64Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64(v))
-	}
-	return b, nil
-}
-func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toInt64Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	// compute size
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v))
-	}
-	b = appendVarint(b, uint64(n))
-	for _, v := range s {
-		b = appendVarint(b, uint64(v))
-	}
-	return b, nil
-}
-func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt32()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
-	return b, nil
-}
-func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt32()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
-	return b, nil
-}
-func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := ptr.getInt32Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	v := *p
-	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
-	return b, nil
-}
-func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := ptr.getInt32Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
-	}
-	return b, nil
-}
-func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := ptr.getInt32Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	// compute size
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
-	}
-	b = appendVarint(b, uint64(n))
-	for _, v := range s {
-		b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
-	}
-	return b, nil
-}
-func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt64()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
-	return b, nil
-}
-func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toInt64()
-	if v == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
-	return b, nil
-}
-func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toInt64Ptr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	v := *p
-	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
-	return b, nil
-}
-func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toInt64Slice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
-	}
-	return b, nil
-}
-func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toInt64Slice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	// compute size
-	n := 0
-	for _, v := range s {
-		n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
-	}
-	b = appendVarint(b, uint64(n))
-	for _, v := range s {
-		b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
-	}
-	return b, nil
-}
-func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toBool()
-	b = appendVarint(b, wiretag)
-	if v {
-		b = append(b, 1)
-	} else {
-		b = append(b, 0)
-	}
-	return b, nil
-}
-func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toBool()
-	if !v {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = append(b, 1)
-	return b, nil
-}
-
-func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toBoolPtr()
-	if p == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	if *p {
-		b = append(b, 1)
-	} else {
-		b = append(b, 0)
-	}
-	return b, nil
-}
-func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toBoolSlice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		if v {
-			b = append(b, 1)
-		} else {
-			b = append(b, 0)
-		}
-	}
-	return b, nil
-}
-func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toBoolSlice()
-	if len(s) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag&^7|WireBytes)
-	b = appendVarint(b, uint64(len(s)))
-	for _, v := range s {
-		if v {
-			b = append(b, 1)
-		} else {
-			b = append(b, 0)
-		}
-	}
-	return b, nil
-}
-func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toString()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	return b, nil
-}
-func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toString()
-	if v == "" {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	return b, nil
-}
-func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	p := *ptr.toStringPtr()
-	if p == nil {
-		return b, nil
-	}
-	v := *p
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	return b, nil
-}
-func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toStringSlice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64(len(v)))
-		b = append(b, v...)
-	}
-	return b, nil
-}
-func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	var invalidUTF8 bool
-	v := *ptr.toString()
-	if !utf8.ValidString(v) {
-		invalidUTF8 = true
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	if invalidUTF8 {
-		return b, errInvalidUTF8
-	}
-	return b, nil
-}
-func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	var invalidUTF8 bool
-	v := *ptr.toString()
-	if v == "" {
-		return b, nil
-	}
-	if !utf8.ValidString(v) {
-		invalidUTF8 = true
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	if invalidUTF8 {
-		return b, errInvalidUTF8
-	}
-	return b, nil
-}
-func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	var invalidUTF8 bool
-	p := *ptr.toStringPtr()
-	if p == nil {
-		return b, nil
-	}
-	v := *p
-	if !utf8.ValidString(v) {
-		invalidUTF8 = true
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	if invalidUTF8 {
-		return b, errInvalidUTF8
-	}
-	return b, nil
-}
-func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	var invalidUTF8 bool
-	s := *ptr.toStringSlice()
-	for _, v := range s {
-		if !utf8.ValidString(v) {
-			invalidUTF8 = true
-		}
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64(len(v)))
-		b = append(b, v...)
-	}
-	if invalidUTF8 {
-		return b, errInvalidUTF8
-	}
-	return b, nil
-}
-func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toBytes()
-	if v == nil {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	return b, nil
-}
-func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toBytes()
-	if len(v) == 0 {
-		return b, nil
-	}
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	return b, nil
-}
-func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	v := *ptr.toBytes()
-	b = appendVarint(b, wiretag)
-	b = appendVarint(b, uint64(len(v)))
-	b = append(b, v...)
-	return b, nil
-}
-func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
-	s := *ptr.toBytesSlice()
-	for _, v := range s {
-		b = appendVarint(b, wiretag)
-		b = appendVarint(b, uint64(len(v)))
-		b = append(b, v...)
-	}
-	return b, nil
-}
-
-// makeGroupMarshaler returns the sizer and marshaler for a group.
-// u is the marshal info of the underlying message.
-func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) {
-	return func(ptr pointer, tagsize int) int {
-			p := ptr.getPointer()
-			if p.isNil() {
-				return 0
-			}
-			return u.size(p) + 2*tagsize
-		},
-		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
-			p := ptr.getPointer()
-			if p.isNil() {
-				return b, nil
-			}
-			var err error
-			b = appendVarint(b, wiretag) // start group
-			b, err = u.marshal(b, p, deterministic)
-			b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
-			return b, err
-		}
-}
-
-// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice.
-// u is the marshal info of the underlying message.
-func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
-	return func(ptr pointer, tagsize int) int {
-			s := ptr.getPointerSlice()
-			n := 0
-			for _, v := range s {
-				if v.isNil() {
-					continue
-				}
-				n += u.size(v) + 2*tagsize
-			}
-			return n
-		},
-		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
-			s := ptr.getPointerSlice()
-			var err error
-			var nerr nonFatal
-			for _, v := range s {
-				if v.isNil() {
-					return b, errRepeatedHasNil
-				}
-				b = appendVarint(b, wiretag) // start group
-				b, err = u.marshal(b, v, deterministic)
-				b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
-				if !nerr.Merge(err) {
-					if err == ErrNil {
-						err = errRepeatedHasNil
-					}
-					return b, err
-				}
-			}
-			return b, nerr.E
-		}
-}
-
-// makeMessageMarshaler returns the sizer and marshaler for a message field.
-// u is the marshal info of the message.
-func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) {
-	return func(ptr pointer, tagsize int) int {
-			p := ptr.getPointer()
-			if p.isNil() {
-				return 0
-			}
-			siz := u.size(p)
-			return siz + SizeVarint(uint64(siz)) + tagsize
-		},
-		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
-			p := ptr.getPointer()
-			if p.isNil() {
-				return b, nil
-			}
-			b = appendVarint(b, wiretag)
-			siz := u.cachedsize(p)
-			b = appendVarint(b, uint64(siz))
-			return u.marshal(b, p, deterministic)
-		}
-}
-
-// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice.
-// u is the marshal info of the message.
-func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
-	return func(ptr pointer, tagsize int) int {
-			s := ptr.getPointerSlice()
-			n := 0
-			for _, v := range s {
-				if v.isNil() {
-					continue
-				}
-				siz := u.size(v)
-				n += siz + SizeVarint(uint64(siz)) + tagsize
-			}
-			return n
-		},
-		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
-			s := ptr.getPointerSlice()
-			var err error
-			var nerr nonFatal
-			for _, v := range s {
-				if v.isNil() {
-					return b, errRepeatedHasNil
-				}
-				b = appendVarint(b, wiretag)
-				siz := u.cachedsize(v)
-				b = appendVarint(b, uint64(siz))
-				b, err = u.marshal(b, v, deterministic)
-
-				if !nerr.Merge(err) {
-					if err == ErrNil {
-						err = errRepeatedHasNil
-					}
-					return b, err
-				}
-			}
-			return b, nerr.E
-		}
-}
-
-// makeMapMarshaler returns the sizer and marshaler for a map field.
-// f is the pointer to the reflect data structure of the field.
-func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
-	// figure out key and value type
-	t := f.Type
-	keyType := t.Key()
-	valType := t.Elem()
-	keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",")
-	valTags := strings.Split(f.Tag.Get("protobuf_val"), ",")
-	keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map
-	valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map
-	keyWireTag := 1<<3 | wiretype(keyTags[0])
-	valWireTag := 2<<3 | wiretype(valTags[0])
-
-	// We create an interface to get the addresses of the map key and value.
-	// If value is pointer-typed, the interface is a direct interface, the
-	// idata itself is the value. Otherwise, the idata is the pointer to the
-	// value.
-	// Key cannot be pointer-typed.
-	valIsPtr := valType.Kind() == reflect.Ptr
-
-	// If value is a message with nested maps, calling
-	// valSizer in marshal may be quadratic. We should use
-	// cached version in marshal (but not in size).
-	// If value is not message type, we don't have size cache,
-	// but it cannot be nested either. Just use valSizer.
-	valCachedSizer := valSizer
-	if valIsPtr && valType.Elem().Kind() == reflect.Struct {
-		u := getMarshalInfo(valType.Elem())
-		valCachedSizer = func(ptr pointer, tagsize int) int {
-			// Same as message sizer, but use cache.
-			p := ptr.getPointer()
-			if p.isNil() {
-				return 0
-			}
-			siz := u.cachedsize(p)
-			return siz + SizeVarint(uint64(siz)) + tagsize
-		}
-	}
-	return func(ptr pointer, tagsize int) int {
-			m := ptr.asPointerTo(t).Elem() // the map
-			n := 0
-			for _, k := range m.MapKeys() {
-				ki := k.Interface()
-				vi := m.MapIndex(k).Interface()
-				kaddr := toAddrPointer(&ki, false)             // pointer to key
-				vaddr := toAddrPointer(&vi, valIsPtr)          // pointer to value
-				siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
-				n += siz + SizeVarint(uint64(siz)) + tagsize
-			}
-			return n
-		},
-		func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) {
-			m := ptr.asPointerTo(t).Elem() // the map
-			var err error
-			keys := m.MapKeys()
-			if len(keys) > 1 && deterministic {
-				sort.Sort(mapKeys(keys))
-			}
-
-			var nerr nonFatal
-			for _, k := range keys {
-				ki := k.Interface()
-				vi := m.MapIndex(k).Interface()
-				kaddr := toAddrPointer(&ki, false)    // pointer to key
-				vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
-				b = appendVarint(b, tag)
-				siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
-				b = appendVarint(b, uint64(siz))
-				b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)
-				if !nerr.Merge(err) {
-					return b, err
-				}
-				b, err = valMarshaler(b, vaddr, valWireTag, deterministic)
-				if err != ErrNil && !nerr.Merge(err) { // allow nil value in map
-					return b, err
-				}
-			}
-			return b, nerr.E
-		}
-}
-
-// makeOneOfMarshaler returns the sizer and marshaler for a oneof field.
-// fi is the marshal info of the field.
-// f is the pointer to the reflect data structure of the field.
-func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) {
-	// Oneof field is an interface. We need to get the actual data type on the fly.
-	t := f.Type
-	return func(ptr pointer, _ int) int {
-			p := ptr.getInterfacePointer()
-			if p.isNil() {
-				return 0
-			}
-			v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
-			telem := v.Type()
-			e := fi.oneofElems[telem]
-			return e.sizer(p, e.tagsize)
-		},
-		func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) {
-			p := ptr.getInterfacePointer()
-			if p.isNil() {
-				return b, nil
-			}
-			v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
-			telem := v.Type()
-			if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() {
-				return b, errOneofHasNil
-			}
-			e := fi.oneofElems[telem]
-			return e.marshaler(b, p, e.wiretag, deterministic)
-		}
-}
-
-// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field.
-func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {
-	m, mu := ext.extensionsRead()
-	if m == nil {
-		return 0
-	}
-	mu.Lock()
-
-	n := 0
-	for _, e := range m {
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			n += len(e.enc)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-		ei := u.getExtElemInfo(e.desc)
-		v := e.value
-		p := toAddrPointer(&v, ei.isptr)
-		n += ei.sizer(p, ei.tagsize)
-	}
-	mu.Unlock()
-	return n
-}
-
-// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b.
-func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
-	m, mu := ext.extensionsRead()
-	if m == nil {
-		return b, nil
-	}
-	mu.Lock()
-	defer mu.Unlock()
-
-	var err error
-	var nerr nonFatal
-
-	// Fast-path for common cases: zero or one extensions.
-	// Don't bother sorting the keys.
-	if len(m) <= 1 {
-		for _, e := range m {
-			if e.value == nil || e.desc == nil {
-				// Extension is only in its encoded form.
-				b = append(b, e.enc...)
-				continue
-			}
-
-			// We don't skip extensions that have an encoded form set,
-			// because the extension value may have been mutated after
-			// the last time this function was called.
-
-			ei := u.getExtElemInfo(e.desc)
-			v := e.value
-			p := toAddrPointer(&v, ei.isptr)
-			b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
-			if !nerr.Merge(err) {
-				return b, err
-			}
-		}
-		return b, nerr.E
-	}
-
-	// Sort the keys to provide a deterministic encoding.
-	// Not sure this is required, but the old code does it.
-	keys := make([]int, 0, len(m))
-	for k := range m {
-		keys = append(keys, int(k))
-	}
-	sort.Ints(keys)
-
-	for _, k := range keys {
-		e := m[int32(k)]
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			b = append(b, e.enc...)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		ei := u.getExtElemInfo(e.desc)
-		v := e.value
-		p := toAddrPointer(&v, ei.isptr)
-		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
-		if !nerr.Merge(err) {
-			return b, err
-		}
-	}
-	return b, nerr.E
-}
-
-// message set format is:
-//   message MessageSet {
-//     repeated group Item = 1 {
-//       required int32 type_id = 2;
-//       required string message = 3;
-//     };
-//   }
-
-// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field
-// in message set format (above).
-func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {
-	m, mu := ext.extensionsRead()
-	if m == nil {
-		return 0
-	}
-	mu.Lock()
-
-	n := 0
-	for id, e := range m {
-		n += 2                          // start group, end group. tag = 1 (size=1)
-		n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1)
-
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
-			siz := len(msgWithLen)
-			n += siz + 1 // message, tag = 3 (size=1)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		ei := u.getExtElemInfo(e.desc)
-		v := e.value
-		p := toAddrPointer(&v, ei.isptr)
-		n += ei.sizer(p, 1) // message, tag = 3 (size=1)
-	}
-	mu.Unlock()
-	return n
-}
-
-// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above)
-// to the end of byte slice b.
-func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
-	m, mu := ext.extensionsRead()
-	if m == nil {
-		return b, nil
-	}
-	mu.Lock()
-	defer mu.Unlock()
-
-	var err error
-	var nerr nonFatal
-
-	// Fast-path for common cases: zero or one extensions.
-	// Don't bother sorting the keys.
-	if len(m) <= 1 {
-		for id, e := range m {
-			b = append(b, 1<<3|WireStartGroup)
-			b = append(b, 2<<3|WireVarint)
-			b = appendVarint(b, uint64(id))
-
-			if e.value == nil || e.desc == nil {
-				// Extension is only in its encoded form.
-				msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
-				b = append(b, 3<<3|WireBytes)
-				b = append(b, msgWithLen...)
-				b = append(b, 1<<3|WireEndGroup)
-				continue
-			}
-
-			// We don't skip extensions that have an encoded form set,
-			// because the extension value may have been mutated after
-			// the last time this function was called.
-
-			ei := u.getExtElemInfo(e.desc)
-			v := e.value
-			p := toAddrPointer(&v, ei.isptr)
-			b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
-			if !nerr.Merge(err) {
-				return b, err
-			}
-			b = append(b, 1<<3|WireEndGroup)
-		}
-		return b, nerr.E
-	}
-
-	// Sort the keys to provide a deterministic encoding.
-	keys := make([]int, 0, len(m))
-	for k := range m {
-		keys = append(keys, int(k))
-	}
-	sort.Ints(keys)
-
-	for _, id := range keys {
-		e := m[int32(id)]
-		b = append(b, 1<<3|WireStartGroup)
-		b = append(b, 2<<3|WireVarint)
-		b = appendVarint(b, uint64(id))
-
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
-			b = append(b, 3<<3|WireBytes)
-			b = append(b, msgWithLen...)
-			b = append(b, 1<<3|WireEndGroup)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		ei := u.getExtElemInfo(e.desc)
-		v := e.value
-		p := toAddrPointer(&v, ei.isptr)
-		b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
-		b = append(b, 1<<3|WireEndGroup)
-		if !nerr.Merge(err) {
-			return b, err
-		}
-	}
-	return b, nerr.E
-}
-
-// sizeV1Extensions computes the size of encoded data for a V1-API extension field.
-func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {
-	if m == nil {
-		return 0
-	}
-
-	n := 0
-	for _, e := range m {
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			n += len(e.enc)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		ei := u.getExtElemInfo(e.desc)
-		v := e.value
-		p := toAddrPointer(&v, ei.isptr)
-		n += ei.sizer(p, ei.tagsize)
-	}
-	return n
-}
-
-// appendV1Extensions marshals a V1-API extension field to the end of byte slice b.
-func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) {
-	if m == nil {
-		return b, nil
-	}
-
-	// Sort the keys to provide a deterministic encoding.
-	keys := make([]int, 0, len(m))
-	for k := range m {
-		keys = append(keys, int(k))
-	}
-	sort.Ints(keys)
-
-	var err error
-	var nerr nonFatal
-	for _, k := range keys {
-		e := m[int32(k)]
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			b = append(b, e.enc...)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		ei := u.getExtElemInfo(e.desc)
-		v := e.value
-		p := toAddrPointer(&v, ei.isptr)
-		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
-		if !nerr.Merge(err) {
-			return b, err
-		}
-	}
-	return b, nerr.E
-}
-
-// newMarshaler is the interface representing objects that can marshal themselves.
-//
-// This exists to support protoc-gen-go generated messages.
-// The proto package will stop type-asserting to this interface in the future.
-//
-// DO NOT DEPEND ON THIS.
-type newMarshaler interface {
-	XXX_Size() int
-	XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
-}
-
-// Size returns the encoded size of a protocol buffer message.
-// This is the main entry point.
-func Size(pb Message) int {
-	if m, ok := pb.(newMarshaler); ok {
-		return m.XXX_Size()
-	}
-	if m, ok := pb.(Marshaler); ok {
-		// If the message can marshal itself, let it do it, for compatibility.
-		// NOTE: This is not efficient.
-		b, _ := m.Marshal()
-		return len(b)
-	}
-	// in case somehow we didn't generate the wrapper
-	if pb == nil {
-		return 0
-	}
-	var info InternalMessageInfo
-	return info.Size(pb)
-}
-
-// Marshal takes a protocol buffer message
-// and encodes it into the wire format, returning the data.
-// This is the main entry point.
-func Marshal(pb Message) ([]byte, error) {
-	if m, ok := pb.(newMarshaler); ok {
-		siz := m.XXX_Size()
-		b := make([]byte, 0, siz)
-		return m.XXX_Marshal(b, false)
-	}
-	if m, ok := pb.(Marshaler); ok {
-		// If the message can marshal itself, let it do it, for compatibility.
-		// NOTE: This is not efficient.
-		return m.Marshal()
-	}
-	// in case somehow we didn't generate the wrapper
-	if pb == nil {
-		return nil, ErrNil
-	}
-	var info InternalMessageInfo
-	siz := info.Size(pb)
-	b := make([]byte, 0, siz)
-	return info.Marshal(b, pb, false)
-}
-
-// Marshal takes a protocol buffer message
-// and encodes it into the wire format, writing the result to the
-// Buffer.
-// This is an alternative entry point. It is not necessary to use
-// a Buffer for most applications.
-func (p *Buffer) Marshal(pb Message) error {
-	var err error
-	if m, ok := pb.(newMarshaler); ok {
-		siz := m.XXX_Size()
-		p.grow(siz) // make sure buf has enough capacity
-		p.buf, err = m.XXX_Marshal(p.buf, p.deterministic)
-		return err
-	}
-	if m, ok := pb.(Marshaler); ok {
-		// If the message can marshal itself, let it do it, for compatibility.
-		// NOTE: This is not efficient.
-		b, err := m.Marshal()
-		p.buf = append(p.buf, b...)
-		return err
-	}
-	// in case somehow we didn't generate the wrapper
-	if pb == nil {
-		return ErrNil
-	}
-	var info InternalMessageInfo
-	siz := info.Size(pb)
-	p.grow(siz) // make sure buf has enough capacity
-	p.buf, err = info.Marshal(p.buf, pb, p.deterministic)
-	return err
-}
-
-// grow grows the buffer's capacity, if necessary, to guarantee space for
-// another n bytes. After grow(n), at least n bytes can be written to the
-// buffer without another allocation.
-func (p *Buffer) grow(n int) {
-	need := len(p.buf) + n
-	if need <= cap(p.buf) {
-		return
-	}
-	newCap := len(p.buf) * 2
-	if newCap < need {
-		newCap = need
-	}
-	p.buf = append(make([]byte, 0, newCap), p.buf...)
-}
diff --git a/vendor/github.com/golang/protobuf/proto/table_merge.go b/vendor/github.com/golang/protobuf/proto/table_merge.go
deleted file mode 100644
index 5525def6a..000000000
--- a/vendor/github.com/golang/protobuf/proto/table_merge.go
+++ /dev/null
@@ -1,654 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2016 The Go Authors.  All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"sync"
-	"sync/atomic"
-)
-
-// Merge merges the src message into dst.
-// This assumes that dst and src of the same type and are non-nil.
-func (a *InternalMessageInfo) Merge(dst, src Message) {
-	mi := atomicLoadMergeInfo(&a.merge)
-	if mi == nil {
-		mi = getMergeInfo(reflect.TypeOf(dst).Elem())
-		atomicStoreMergeInfo(&a.merge, mi)
-	}
-	mi.merge(toPointer(&dst), toPointer(&src))
-}
-
-type mergeInfo struct {
-	typ reflect.Type
-
-	initialized int32 // 0: only typ is valid, 1: everything is valid
-	lock        sync.Mutex
-
-	fields       []mergeFieldInfo
-	unrecognized field // Offset of XXX_unrecognized
-}
-
-type mergeFieldInfo struct {
-	field field // Offset of field, guaranteed to be valid
-
-	// isPointer reports whether the value in the field is a pointer.
-	// This is true for the following situations:
-	//	* Pointer to struct
-	//	* Pointer to basic type (proto2 only)
-	//	* Slice (first value in slice header is a pointer)
-	//	* String (first value in string header is a pointer)
-	isPointer bool
-
-	// basicWidth reports the width of the field assuming that it is directly
-	// embedded in the struct (as is the case for basic types in proto3).
-	// The possible values are:
-	// 	0: invalid
-	//	1: bool
-	//	4: int32, uint32, float32
-	//	8: int64, uint64, float64
-	basicWidth int
-
-	// Where dst and src are pointers to the types being merged.
-	merge func(dst, src pointer)
-}
-
-var (
-	mergeInfoMap  = map[reflect.Type]*mergeInfo{}
-	mergeInfoLock sync.Mutex
-)
-
-func getMergeInfo(t reflect.Type) *mergeInfo {
-	mergeInfoLock.Lock()
-	defer mergeInfoLock.Unlock()
-	mi := mergeInfoMap[t]
-	if mi == nil {
-		mi = &mergeInfo{typ: t}
-		mergeInfoMap[t] = mi
-	}
-	return mi
-}
-
-// merge merges src into dst assuming they are both of type *mi.typ.
-func (mi *mergeInfo) merge(dst, src pointer) {
-	if dst.isNil() {
-		panic("proto: nil destination")
-	}
-	if src.isNil() {
-		return // Nothing to do.
-	}
-
-	if atomic.LoadInt32(&mi.initialized) == 0 {
-		mi.computeMergeInfo()
-	}
-
-	for _, fi := range mi.fields {
-		sfp := src.offset(fi.field)
-
-		// As an optimization, we can avoid the merge function call cost
-		// if we know for sure that the source will have no effect
-		// by checking if it is the zero value.
-		if unsafeAllowed {
-			if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string
-				continue
-			}
-			if fi.basicWidth > 0 {
-				switch {
-				case fi.basicWidth == 1 && !*sfp.toBool():
-					continue
-				case fi.basicWidth == 4 && *sfp.toUint32() == 0:
-					continue
-				case fi.basicWidth == 8 && *sfp.toUint64() == 0:
-					continue
-				}
-			}
-		}
-
-		dfp := dst.offset(fi.field)
-		fi.merge(dfp, sfp)
-	}
-
-	// TODO: Make this faster?
-	out := dst.asPointerTo(mi.typ).Elem()
-	in := src.asPointerTo(mi.typ).Elem()
-	if emIn, err := extendable(in.Addr().Interface()); err == nil {
-		emOut, _ := extendable(out.Addr().Interface())
-		mIn, muIn := emIn.extensionsRead()
-		if mIn != nil {
-			mOut := emOut.extensionsWrite()
-			muIn.Lock()
-			mergeExtension(mOut, mIn)
-			muIn.Unlock()
-		}
-	}
-
-	if mi.unrecognized.IsValid() {
-		if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 {
-			*dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...)
-		}
-	}
-}
-
-func (mi *mergeInfo) computeMergeInfo() {
-	mi.lock.Lock()
-	defer mi.lock.Unlock()
-	if mi.initialized != 0 {
-		return
-	}
-	t := mi.typ
-	n := t.NumField()
-
-	props := GetProperties(t)
-	for i := 0; i < n; i++ {
-		f := t.Field(i)
-		if strings.HasPrefix(f.Name, "XXX_") {
-			continue
-		}
-
-		mfi := mergeFieldInfo{field: toField(&f)}
-		tf := f.Type
-
-		// As an optimization, we can avoid the merge function call cost
-		// if we know for sure that the source will have no effect
-		// by checking if it is the zero value.
-		if unsafeAllowed {
-			switch tf.Kind() {
-			case reflect.Ptr, reflect.Slice, reflect.String:
-				// As a special case, we assume slices and strings are pointers
-				// since we know that the first field in the SliceSlice or
-				// StringHeader is a data pointer.
-				mfi.isPointer = true
-			case reflect.Bool:
-				mfi.basicWidth = 1
-			case reflect.Int32, reflect.Uint32, reflect.Float32:
-				mfi.basicWidth = 4
-			case reflect.Int64, reflect.Uint64, reflect.Float64:
-				mfi.basicWidth = 8
-			}
-		}
-
-		// Unwrap tf to get at its most basic type.
-		var isPointer, isSlice bool
-		if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
-			isSlice = true
-			tf = tf.Elem()
-		}
-		if tf.Kind() == reflect.Ptr {
-			isPointer = true
-			tf = tf.Elem()
-		}
-		if isPointer && isSlice && tf.Kind() != reflect.Struct {
-			panic("both pointer and slice for basic type in " + tf.Name())
-		}
-
-		switch tf.Kind() {
-		case reflect.Int32:
-			switch {
-			case isSlice: // E.g., []int32
-				mfi.merge = func(dst, src pointer) {
-					// NOTE: toInt32Slice is not defined (see pointer_reflect.go).
-					/*
-						sfsp := src.toInt32Slice()
-						if *sfsp != nil {
-							dfsp := dst.toInt32Slice()
-							*dfsp = append(*dfsp, *sfsp...)
-							if *dfsp == nil {
-								*dfsp = []int64{}
-							}
-						}
-					*/
-					sfs := src.getInt32Slice()
-					if sfs != nil {
-						dfs := dst.getInt32Slice()
-						dfs = append(dfs, sfs...)
-						if dfs == nil {
-							dfs = []int32{}
-						}
-						dst.setInt32Slice(dfs)
-					}
-				}
-			case isPointer: // E.g., *int32
-				mfi.merge = func(dst, src pointer) {
-					// NOTE: toInt32Ptr is not defined (see pointer_reflect.go).
-					/*
-						sfpp := src.toInt32Ptr()
-						if *sfpp != nil {
-							dfpp := dst.toInt32Ptr()
-							if *dfpp == nil {
-								*dfpp = Int32(**sfpp)
-							} else {
-								**dfpp = **sfpp
-							}
-						}
-					*/
-					sfp := src.getInt32Ptr()
-					if sfp != nil {
-						dfp := dst.getInt32Ptr()
-						if dfp == nil {
-							dst.setInt32Ptr(*sfp)
-						} else {
-							*dfp = *sfp
-						}
-					}
-				}
-			default: // E.g., int32
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toInt32(); v != 0 {
-						*dst.toInt32() = v
-					}
-				}
-			}
-		case reflect.Int64:
-			switch {
-			case isSlice: // E.g., []int64
-				mfi.merge = func(dst, src pointer) {
-					sfsp := src.toInt64Slice()
-					if *sfsp != nil {
-						dfsp := dst.toInt64Slice()
-						*dfsp = append(*dfsp, *sfsp...)
-						if *dfsp == nil {
-							*dfsp = []int64{}
-						}
-					}
-				}
-			case isPointer: // E.g., *int64
-				mfi.merge = func(dst, src pointer) {
-					sfpp := src.toInt64Ptr()
-					if *sfpp != nil {
-						dfpp := dst.toInt64Ptr()
-						if *dfpp == nil {
-							*dfpp = Int64(**sfpp)
-						} else {
-							**dfpp = **sfpp
-						}
-					}
-				}
-			default: // E.g., int64
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toInt64(); v != 0 {
-						*dst.toInt64() = v
-					}
-				}
-			}
-		case reflect.Uint32:
-			switch {
-			case isSlice: // E.g., []uint32
-				mfi.merge = func(dst, src pointer) {
-					sfsp := src.toUint32Slice()
-					if *sfsp != nil {
-						dfsp := dst.toUint32Slice()
-						*dfsp = append(*dfsp, *sfsp...)
-						if *dfsp == nil {
-							*dfsp = []uint32{}
-						}
-					}
-				}
-			case isPointer: // E.g., *uint32
-				mfi.merge = func(dst, src pointer) {
-					sfpp := src.toUint32Ptr()
-					if *sfpp != nil {
-						dfpp := dst.toUint32Ptr()
-						if *dfpp == nil {
-							*dfpp = Uint32(**sfpp)
-						} else {
-							**dfpp = **sfpp
-						}
-					}
-				}
-			default: // E.g., uint32
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toUint32(); v != 0 {
-						*dst.toUint32() = v
-					}
-				}
-			}
-		case reflect.Uint64:
-			switch {
-			case isSlice: // E.g., []uint64
-				mfi.merge = func(dst, src pointer) {
-					sfsp := src.toUint64Slice()
-					if *sfsp != nil {
-						dfsp := dst.toUint64Slice()
-						*dfsp = append(*dfsp, *sfsp...)
-						if *dfsp == nil {
-							*dfsp = []uint64{}
-						}
-					}
-				}
-			case isPointer: // E.g., *uint64
-				mfi.merge = func(dst, src pointer) {
-					sfpp := src.toUint64Ptr()
-					if *sfpp != nil {
-						dfpp := dst.toUint64Ptr()
-						if *dfpp == nil {
-							*dfpp = Uint64(**sfpp)
-						} else {
-							**dfpp = **sfpp
-						}
-					}
-				}
-			default: // E.g., uint64
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toUint64(); v != 0 {
-						*dst.toUint64() = v
-					}
-				}
-			}
-		case reflect.Float32:
-			switch {
-			case isSlice: // E.g., []float32
-				mfi.merge = func(dst, src pointer) {
-					sfsp := src.toFloat32Slice()
-					if *sfsp != nil {
-						dfsp := dst.toFloat32Slice()
-						*dfsp = append(*dfsp, *sfsp...)
-						if *dfsp == nil {
-							*dfsp = []float32{}
-						}
-					}
-				}
-			case isPointer: // E.g., *float32
-				mfi.merge = func(dst, src pointer) {
-					sfpp := src.toFloat32Ptr()
-					if *sfpp != nil {
-						dfpp := dst.toFloat32Ptr()
-						if *dfpp == nil {
-							*dfpp = Float32(**sfpp)
-						} else {
-							**dfpp = **sfpp
-						}
-					}
-				}
-			default: // E.g., float32
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toFloat32(); v != 0 {
-						*dst.toFloat32() = v
-					}
-				}
-			}
-		case reflect.Float64:
-			switch {
-			case isSlice: // E.g., []float64
-				mfi.merge = func(dst, src pointer) {
-					sfsp := src.toFloat64Slice()
-					if *sfsp != nil {
-						dfsp := dst.toFloat64Slice()
-						*dfsp = append(*dfsp, *sfsp...)
-						if *dfsp == nil {
-							*dfsp = []float64{}
-						}
-					}
-				}
-			case isPointer: // E.g., *float64
-				mfi.merge = func(dst, src pointer) {
-					sfpp := src.toFloat64Ptr()
-					if *sfpp != nil {
-						dfpp := dst.toFloat64Ptr()
-						if *dfpp == nil {
-							*dfpp = Float64(**sfpp)
-						} else {
-							**dfpp = **sfpp
-						}
-					}
-				}
-			default: // E.g., float64
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toFloat64(); v != 0 {
-						*dst.toFloat64() = v
-					}
-				}
-			}
-		case reflect.Bool:
-			switch {
-			case isSlice: // E.g., []bool
-				mfi.merge = func(dst, src pointer) {
-					sfsp := src.toBoolSlice()
-					if *sfsp != nil {
-						dfsp := dst.toBoolSlice()
-						*dfsp = append(*dfsp, *sfsp...)
-						if *dfsp == nil {
-							*dfsp = []bool{}
-						}
-					}
-				}
-			case isPointer: // E.g., *bool
-				mfi.merge = func(dst, src pointer) {
-					sfpp := src.toBoolPtr()
-					if *sfpp != nil {
-						dfpp := dst.toBoolPtr()
-						if *dfpp == nil {
-							*dfpp = Bool(**sfpp)
-						} else {
-							**dfpp = **sfpp
-						}
-					}
-				}
-			default: // E.g., bool
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toBool(); v {
-						*dst.toBool() = v
-					}
-				}
-			}
-		case reflect.String:
-			switch {
-			case isSlice: // E.g., []string
-				mfi.merge = func(dst, src pointer) {
-					sfsp := src.toStringSlice()
-					if *sfsp != nil {
-						dfsp := dst.toStringSlice()
-						*dfsp = append(*dfsp, *sfsp...)
-						if *dfsp == nil {
-							*dfsp = []string{}
-						}
-					}
-				}
-			case isPointer: // E.g., *string
-				mfi.merge = func(dst, src pointer) {
-					sfpp := src.toStringPtr()
-					if *sfpp != nil {
-						dfpp := dst.toStringPtr()
-						if *dfpp == nil {
-							*dfpp = String(**sfpp)
-						} else {
-							**dfpp = **sfpp
-						}
-					}
-				}
-			default: // E.g., string
-				mfi.merge = func(dst, src pointer) {
-					if v := *src.toString(); v != "" {
-						*dst.toString() = v
-					}
-				}
-			}
-		case reflect.Slice:
-			isProto3 := props.Prop[i].proto3
-			switch {
-			case isPointer:
-				panic("bad pointer in byte slice case in " + tf.Name())
-			case tf.Elem().Kind() != reflect.Uint8:
-				panic("bad element kind in byte slice case in " + tf.Name())
-			case isSlice: // E.g., [][]byte
-				mfi.merge = func(dst, src pointer) {
-					sbsp := src.toBytesSlice()
-					if *sbsp != nil {
-						dbsp := dst.toBytesSlice()
-						for _, sb := range *sbsp {
-							if sb == nil {
-								*dbsp = append(*dbsp, nil)
-							} else {
-								*dbsp = append(*dbsp, append([]byte{}, sb...))
-							}
-						}
-						if *dbsp == nil {
-							*dbsp = [][]byte{}
-						}
-					}
-				}
-			default: // E.g., []byte
-				mfi.merge = func(dst, src pointer) {
-					sbp := src.toBytes()
-					if *sbp != nil {
-						dbp := dst.toBytes()
-						if !isProto3 || len(*sbp) > 0 {
-							*dbp = append([]byte{}, *sbp...)
-						}
-					}
-				}
-			}
-		case reflect.Struct:
-			switch {
-			case !isPointer:
-				panic(fmt.Sprintf("message field %s without pointer", tf))
-			case isSlice: // E.g., []*pb.T
-				mi := getMergeInfo(tf)
-				mfi.merge = func(dst, src pointer) {
-					sps := src.getPointerSlice()
-					if sps != nil {
-						dps := dst.getPointerSlice()
-						for _, sp := range sps {
-							var dp pointer
-							if !sp.isNil() {
-								dp = valToPointer(reflect.New(tf))
-								mi.merge(dp, sp)
-							}
-							dps = append(dps, dp)
-						}
-						if dps == nil {
-							dps = []pointer{}
-						}
-						dst.setPointerSlice(dps)
-					}
-				}
-			default: // E.g., *pb.T
-				mi := getMergeInfo(tf)
-				mfi.merge = func(dst, src pointer) {
-					sp := src.getPointer()
-					if !sp.isNil() {
-						dp := dst.getPointer()
-						if dp.isNil() {
-							dp = valToPointer(reflect.New(tf))
-							dst.setPointer(dp)
-						}
-						mi.merge(dp, sp)
-					}
-				}
-			}
-		case reflect.Map:
-			switch {
-			case isPointer || isSlice:
-				panic("bad pointer or slice in map case in " + tf.Name())
-			default: // E.g., map[K]V
-				mfi.merge = func(dst, src pointer) {
-					sm := src.asPointerTo(tf).Elem()
-					if sm.Len() == 0 {
-						return
-					}
-					dm := dst.asPointerTo(tf).Elem()
-					if dm.IsNil() {
-						dm.Set(reflect.MakeMap(tf))
-					}
-
-					switch tf.Elem().Kind() {
-					case reflect.Ptr: // Proto struct (e.g., *T)
-						for _, key := range sm.MapKeys() {
-							val := sm.MapIndex(key)
-							val = reflect.ValueOf(Clone(val.Interface().(Message)))
-							dm.SetMapIndex(key, val)
-						}
-					case reflect.Slice: // E.g. Bytes type (e.g., []byte)
-						for _, key := range sm.MapKeys() {
-							val := sm.MapIndex(key)
-							val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
-							dm.SetMapIndex(key, val)
-						}
-					default: // Basic type (e.g., string)
-						for _, key := range sm.MapKeys() {
-							val := sm.MapIndex(key)
-							dm.SetMapIndex(key, val)
-						}
-					}
-				}
-			}
-		case reflect.Interface:
-			// Must be oneof field.
-			switch {
-			case isPointer || isSlice:
-				panic("bad pointer or slice in interface case in " + tf.Name())
-			default: // E.g., interface{}
-				// TODO: Make this faster?
-				mfi.merge = func(dst, src pointer) {
-					su := src.asPointerTo(tf).Elem()
-					if !su.IsNil() {
-						du := dst.asPointerTo(tf).Elem()
-						typ := su.Elem().Type()
-						if du.IsNil() || du.Elem().Type() != typ {
-							du.Set(reflect.New(typ.Elem())) // Initialize interface if empty
-						}
-						sv := su.Elem().Elem().Field(0)
-						if sv.Kind() == reflect.Ptr && sv.IsNil() {
-							return
-						}
-						dv := du.Elem().Elem().Field(0)
-						if dv.Kind() == reflect.Ptr && dv.IsNil() {
-							dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty
-						}
-						switch sv.Type().Kind() {
-						case reflect.Ptr: // Proto struct (e.g., *T)
-							Merge(dv.Interface().(Message), sv.Interface().(Message))
-						case reflect.Slice: // E.g. Bytes type (e.g., []byte)
-							dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...)))
-						default: // Basic type (e.g., string)
-							dv.Set(sv)
-						}
-					}
-				}
-			}
-		default:
-			panic(fmt.Sprintf("merger not found for type:%s", tf))
-		}
-		mi.fields = append(mi.fields, mfi)
-	}
-
-	mi.unrecognized = invalidField
-	if f, ok := t.FieldByName("XXX_unrecognized"); ok {
-		if f.Type != reflect.TypeOf([]byte{}) {
-			panic("expected XXX_unrecognized to be of type []byte")
-		}
-		mi.unrecognized = toField(&f)
-	}
-
-	atomic.StoreInt32(&mi.initialized, 1)
-}
diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
deleted file mode 100644
index ebf1caa56..000000000
--- a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
+++ /dev/null
@@ -1,2051 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2016 The Go Authors.  All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"strconv"
-	"strings"
-	"sync"
-	"sync/atomic"
-	"unicode/utf8"
-)
-
-// Unmarshal is the entry point from the generated .pb.go files.
-// This function is not intended to be used by non-generated code.
-// This function is not subject to any compatibility guarantee.
-// msg contains a pointer to a protocol buffer struct.
-// b is the data to be unmarshaled into the protocol buffer.
-// a is a pointer to a place to store cached unmarshal information.
-func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error {
-	// Load the unmarshal information for this message type.
-	// The atomic load ensures memory consistency.
-	u := atomicLoadUnmarshalInfo(&a.unmarshal)
-	if u == nil {
-		// Slow path: find unmarshal info for msg, update a with it.
-		u = getUnmarshalInfo(reflect.TypeOf(msg).Elem())
-		atomicStoreUnmarshalInfo(&a.unmarshal, u)
-	}
-	// Then do the unmarshaling.
-	err := u.unmarshal(toPointer(&msg), b)
-	return err
-}
-
-type unmarshalInfo struct {
-	typ reflect.Type // type of the protobuf struct
-
-	// 0 = only typ field is initialized
-	// 1 = completely initialized
-	initialized     int32
-	lock            sync.Mutex                    // prevents double initialization
-	dense           []unmarshalFieldInfo          // fields indexed by tag #
-	sparse          map[uint64]unmarshalFieldInfo // fields indexed by tag #
-	reqFields       []string                      // names of required fields
-	reqMask         uint64                        // 1<<len(reqFields)-1
-	unrecognized    field                         // offset of []byte to put unrecognized data (or invalidField if we should throw it away)
-	extensions      field                         // offset of extensions field (of type proto.XXX_InternalExtensions), or invalidField if it does not exist
-	oldExtensions   field                         // offset of old-form extensions field (of type map[int]Extension)
-	extensionRanges []ExtensionRange              // if non-nil, implies extensions field is valid
-	isMessageSet    bool                          // if true, implies extensions field is valid
-}
-
-// An unmarshaler takes a stream of bytes and a pointer to a field of a message.
-// It decodes the field, stores it at f, and returns the unused bytes.
-// w is the wire encoding.
-// b is the data after the tag and wire encoding have been read.
-type unmarshaler func(b []byte, f pointer, w int) ([]byte, error)
-
-type unmarshalFieldInfo struct {
-	// location of the field in the proto message structure.
-	field field
-
-	// function to unmarshal the data for the field.
-	unmarshal unmarshaler
-
-	// if a required field, contains a single set bit at this field's index in the required field list.
-	reqMask uint64
-
-	name string // name of the field, for error reporting
-}
-
-var (
-	unmarshalInfoMap  = map[reflect.Type]*unmarshalInfo{}
-	unmarshalInfoLock sync.Mutex
-)
-
-// getUnmarshalInfo returns the data structure which can be
-// subsequently used to unmarshal a message of the given type.
-// t is the type of the message (note: not pointer to message).
-func getUnmarshalInfo(t reflect.Type) *unmarshalInfo {
-	// It would be correct to return a new unmarshalInfo
-	// unconditionally. We would end up allocating one
-	// per occurrence of that type as a message or submessage.
-	// We use a cache here just to reduce memory usage.
-	unmarshalInfoLock.Lock()
-	defer unmarshalInfoLock.Unlock()
-	u := unmarshalInfoMap[t]
-	if u == nil {
-		u = &unmarshalInfo{typ: t}
-		// Note: we just set the type here. The rest of the fields
-		// will be initialized on first use.
-		unmarshalInfoMap[t] = u
-	}
-	return u
-}
-
-// unmarshal does the main work of unmarshaling a message.
-// u provides type information used to unmarshal the message.
-// m is a pointer to a protocol buffer message.
-// b is a byte stream to unmarshal into m.
-// This is top routine used when recursively unmarshaling submessages.
-func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
-	if atomic.LoadInt32(&u.initialized) == 0 {
-		u.computeUnmarshalInfo()
-	}
-	if u.isMessageSet {
-		return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
-	}
-	var reqMask uint64 // bitmask of required fields we've seen.
-	var errLater error
-	for len(b) > 0 {
-		// Read tag and wire type.
-		// Special case 1 and 2 byte varints.
-		var x uint64
-		if b[0] < 128 {
-			x = uint64(b[0])
-			b = b[1:]
-		} else if len(b) >= 2 && b[1] < 128 {
-			x = uint64(b[0]&0x7f) + uint64(b[1])<<7
-			b = b[2:]
-		} else {
-			var n int
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return io.ErrUnexpectedEOF
-			}
-			b = b[n:]
-		}
-		tag := x >> 3
-		wire := int(x) & 7
-
-		// Dispatch on the tag to one of the unmarshal* functions below.
-		var f unmarshalFieldInfo
-		if tag < uint64(len(u.dense)) {
-			f = u.dense[tag]
-		} else {
-			f = u.sparse[tag]
-		}
-		if fn := f.unmarshal; fn != nil {
-			var err error
-			b, err = fn(b, m.offset(f.field), wire)
-			if err == nil {
-				reqMask |= f.reqMask
-				continue
-			}
-			if r, ok := err.(*RequiredNotSetError); ok {
-				// Remember this error, but keep parsing. We need to produce
-				// a full parse even if a required field is missing.
-				if errLater == nil {
-					errLater = r
-				}
-				reqMask |= f.reqMask
-				continue
-			}
-			if err != errInternalBadWireType {
-				if err == errInvalidUTF8 {
-					if errLater == nil {
-						fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
-						errLater = &invalidUTF8Error{fullName}
-					}
-					continue
-				}
-				return err
-			}
-			// Fragments with bad wire type are treated as unknown fields.
-		}
-
-		// Unknown tag.
-		if !u.unrecognized.IsValid() {
-			// Don't keep unrecognized data; just skip it.
-			var err error
-			b, err = skipField(b, wire)
-			if err != nil {
-				return err
-			}
-			continue
-		}
-		// Keep unrecognized data around.
-		// maybe in extensions, maybe in the unrecognized field.
-		z := m.offset(u.unrecognized).toBytes()
-		var emap map[int32]Extension
-		var e Extension
-		for _, r := range u.extensionRanges {
-			if uint64(r.Start) <= tag && tag <= uint64(r.End) {
-				if u.extensions.IsValid() {
-					mp := m.offset(u.extensions).toExtensions()
-					emap = mp.extensionsWrite()
-					e = emap[int32(tag)]
-					z = &e.enc
-					break
-				}
-				if u.oldExtensions.IsValid() {
-					p := m.offset(u.oldExtensions).toOldExtensions()
-					emap = *p
-					if emap == nil {
-						emap = map[int32]Extension{}
-						*p = emap
-					}
-					e = emap[int32(tag)]
-					z = &e.enc
-					break
-				}
-				panic("no extensions field available")
-			}
-		}
-
-		// Use wire type to skip data.
-		var err error
-		b0 := b
-		b, err = skipField(b, wire)
-		if err != nil {
-			return err
-		}
-		*z = encodeVarint(*z, tag<<3|uint64(wire))
-		*z = append(*z, b0[:len(b0)-len(b)]...)
-
-		if emap != nil {
-			emap[int32(tag)] = e
-		}
-	}
-	if reqMask != u.reqMask && errLater == nil {
-		// A required field of this message is missing.
-		for _, n := range u.reqFields {
-			if reqMask&1 == 0 {
-				errLater = &RequiredNotSetError{n}
-			}
-			reqMask >>= 1
-		}
-	}
-	return errLater
-}
-
-// computeUnmarshalInfo fills in u with information for use
-// in unmarshaling protocol buffers of type u.typ.
-func (u *unmarshalInfo) computeUnmarshalInfo() {
-	u.lock.Lock()
-	defer u.lock.Unlock()
-	if u.initialized != 0 {
-		return
-	}
-	t := u.typ
-	n := t.NumField()
-
-	// Set up the "not found" value for the unrecognized byte buffer.
-	// This is the default for proto3.
-	u.unrecognized = invalidField
-	u.extensions = invalidField
-	u.oldExtensions = invalidField
-
-	// List of the generated type and offset for each oneof field.
-	type oneofField struct {
-		ityp  reflect.Type // interface type of oneof field
-		field field        // offset in containing message
-	}
-	var oneofFields []oneofField
-
-	for i := 0; i < n; i++ {
-		f := t.Field(i)
-		if f.Name == "XXX_unrecognized" {
-			// The byte slice used to hold unrecognized input is special.
-			if f.Type != reflect.TypeOf(([]byte)(nil)) {
-				panic("bad type for XXX_unrecognized field: " + f.Type.Name())
-			}
-			u.unrecognized = toField(&f)
-			continue
-		}
-		if f.Name == "XXX_InternalExtensions" {
-			// Ditto here.
-			if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) {
-				panic("bad type for XXX_InternalExtensions field: " + f.Type.Name())
-			}
-			u.extensions = toField(&f)
-			if f.Tag.Get("protobuf_messageset") == "1" {
-				u.isMessageSet = true
-			}
-			continue
-		}
-		if f.Name == "XXX_extensions" {
-			// An older form of the extensions field.
-			if f.Type != reflect.TypeOf((map[int32]Extension)(nil)) {
-				panic("bad type for XXX_extensions field: " + f.Type.Name())
-			}
-			u.oldExtensions = toField(&f)
-			continue
-		}
-		if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" {
-			continue
-		}
-
-		oneof := f.Tag.Get("protobuf_oneof")
-		if oneof != "" {
-			oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)})
-			// The rest of oneof processing happens below.
-			continue
-		}
-
-		tags := f.Tag.Get("protobuf")
-		tagArray := strings.Split(tags, ",")
-		if len(tagArray) < 2 {
-			panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags)
-		}
-		tag, err := strconv.Atoi(tagArray[1])
-		if err != nil {
-			panic("protobuf tag field not an integer: " + tagArray[1])
-		}
-
-		name := ""
-		for _, tag := range tagArray[3:] {
-			if strings.HasPrefix(tag, "name=") {
-				name = tag[5:]
-			}
-		}
-
-		// Extract unmarshaling function from the field (its type and tags).
-		unmarshal := fieldUnmarshaler(&f)
-
-		// Required field?
-		var reqMask uint64
-		if tagArray[2] == "req" {
-			bit := len(u.reqFields)
-			u.reqFields = append(u.reqFields, name)
-			reqMask = uint64(1) << uint(bit)
-			// TODO: if we have more than 64 required fields, we end up
-			// not verifying that all required fields are present.
-			// Fix this, perhaps using a count of required fields?
-		}
-
-		// Store the info in the correct slot in the message.
-		u.setTag(tag, toField(&f), unmarshal, reqMask, name)
-	}
-
-	// Find any types associated with oneof fields.
-	// TODO: XXX_OneofFuncs returns more info than we need.  Get rid of some of it?
-	fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs")
-	if fn.IsValid() {
-		res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{}
-		for i := res.Len() - 1; i >= 0; i-- {
-			v := res.Index(i)                             // interface{}
-			tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X
-			typ := tptr.Elem()                            // Msg_X
-
-			f := typ.Field(0) // oneof implementers have one field
-			baseUnmarshal := fieldUnmarshaler(&f)
-			tags := strings.Split(f.Tag.Get("protobuf"), ",")
-			fieldNum, err := strconv.Atoi(tags[1])
-			if err != nil {
-				panic("protobuf tag field not an integer: " + tags[1])
-			}
-			var name string
-			for _, tag := range tags {
-				if strings.HasPrefix(tag, "name=") {
-					name = strings.TrimPrefix(tag, "name=")
-					break
-				}
-			}
-
-			// Find the oneof field that this struct implements.
-			// Might take O(n^2) to process all of the oneofs, but who cares.
-			for _, of := range oneofFields {
-				if tptr.Implements(of.ityp) {
-					// We have found the corresponding interface for this struct.
-					// That lets us know where this struct should be stored
-					// when we encounter it during unmarshaling.
-					unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
-					u.setTag(fieldNum, of.field, unmarshal, 0, name)
-				}
-			}
-		}
-	}
-
-	// Get extension ranges, if any.
-	fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
-	if fn.IsValid() {
-		if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
-			panic("a message with extensions, but no extensions field in " + t.Name())
-		}
-		u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange)
-	}
-
-	// Explicitly disallow tag 0. This will ensure we flag an error
-	// when decoding a buffer of all zeros. Without this code, we
-	// would decode and skip an all-zero buffer of even length.
-	// [0 0] is [tag=0/wiretype=varint varint-encoded-0].
-	u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) {
-		return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w)
-	}, 0, "")
-
-	// Set mask for required field check.
-	u.reqMask = uint64(1)<<uint(len(u.reqFields)) - 1
-
-	atomic.StoreInt32(&u.initialized, 1)
-}
-
-// setTag stores the unmarshal information for the given tag.
-// tag = tag # for field
-// field/unmarshal = unmarshal info for that field.
-// reqMask = if required, bitmask for field position in required field list. 0 otherwise.
-// name = short name of the field.
-func (u *unmarshalInfo) setTag(tag int, field field, unmarshal unmarshaler, reqMask uint64, name string) {
-	i := unmarshalFieldInfo{field: field, unmarshal: unmarshal, reqMask: reqMask, name: name}
-	n := u.typ.NumField()
-	if tag >= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here?
-		for len(u.dense) <= tag {
-			u.dense = append(u.dense, unmarshalFieldInfo{})
-		}
-		u.dense[tag] = i
-		return
-	}
-	if u.sparse == nil {
-		u.sparse = map[uint64]unmarshalFieldInfo{}
-	}
-	u.sparse[uint64(tag)] = i
-}
-
-// fieldUnmarshaler returns an unmarshaler for the given field.
-func fieldUnmarshaler(f *reflect.StructField) unmarshaler {
-	if f.Type.Kind() == reflect.Map {
-		return makeUnmarshalMap(f)
-	}
-	return typeUnmarshaler(f.Type, f.Tag.Get("protobuf"))
-}
-
-// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair.
-func typeUnmarshaler(t reflect.Type, tags string) unmarshaler {
-	tagArray := strings.Split(tags, ",")
-	encoding := tagArray[0]
-	name := "unknown"
-	proto3 := false
-	validateUTF8 := true
-	for _, tag := range tagArray[3:] {
-		if strings.HasPrefix(tag, "name=") {
-			name = tag[5:]
-		}
-		if tag == "proto3" {
-			proto3 = true
-		}
-	}
-	validateUTF8 = validateUTF8 && proto3
-
-	// Figure out packaging (pointer, slice, or both)
-	slice := false
-	pointer := false
-	if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
-		slice = true
-		t = t.Elem()
-	}
-	if t.Kind() == reflect.Ptr {
-		pointer = true
-		t = t.Elem()
-	}
-
-	// We'll never have both pointer and slice for basic types.
-	if pointer && slice && t.Kind() != reflect.Struct {
-		panic("both pointer and slice for basic type in " + t.Name())
-	}
-
-	switch t.Kind() {
-	case reflect.Bool:
-		if pointer {
-			return unmarshalBoolPtr
-		}
-		if slice {
-			return unmarshalBoolSlice
-		}
-		return unmarshalBoolValue
-	case reflect.Int32:
-		switch encoding {
-		case "fixed32":
-			if pointer {
-				return unmarshalFixedS32Ptr
-			}
-			if slice {
-				return unmarshalFixedS32Slice
-			}
-			return unmarshalFixedS32Value
-		case "varint":
-			// this could be int32 or enum
-			if pointer {
-				return unmarshalInt32Ptr
-			}
-			if slice {
-				return unmarshalInt32Slice
-			}
-			return unmarshalInt32Value
-		case "zigzag32":
-			if pointer {
-				return unmarshalSint32Ptr
-			}
-			if slice {
-				return unmarshalSint32Slice
-			}
-			return unmarshalSint32Value
-		}
-	case reflect.Int64:
-		switch encoding {
-		case "fixed64":
-			if pointer {
-				return unmarshalFixedS64Ptr
-			}
-			if slice {
-				return unmarshalFixedS64Slice
-			}
-			return unmarshalFixedS64Value
-		case "varint":
-			if pointer {
-				return unmarshalInt64Ptr
-			}
-			if slice {
-				return unmarshalInt64Slice
-			}
-			return unmarshalInt64Value
-		case "zigzag64":
-			if pointer {
-				return unmarshalSint64Ptr
-			}
-			if slice {
-				return unmarshalSint64Slice
-			}
-			return unmarshalSint64Value
-		}
-	case reflect.Uint32:
-		switch encoding {
-		case "fixed32":
-			if pointer {
-				return unmarshalFixed32Ptr
-			}
-			if slice {
-				return unmarshalFixed32Slice
-			}
-			return unmarshalFixed32Value
-		case "varint":
-			if pointer {
-				return unmarshalUint32Ptr
-			}
-			if slice {
-				return unmarshalUint32Slice
-			}
-			return unmarshalUint32Value
-		}
-	case reflect.Uint64:
-		switch encoding {
-		case "fixed64":
-			if pointer {
-				return unmarshalFixed64Ptr
-			}
-			if slice {
-				return unmarshalFixed64Slice
-			}
-			return unmarshalFixed64Value
-		case "varint":
-			if pointer {
-				return unmarshalUint64Ptr
-			}
-			if slice {
-				return unmarshalUint64Slice
-			}
-			return unmarshalUint64Value
-		}
-	case reflect.Float32:
-		if pointer {
-			return unmarshalFloat32Ptr
-		}
-		if slice {
-			return unmarshalFloat32Slice
-		}
-		return unmarshalFloat32Value
-	case reflect.Float64:
-		if pointer {
-			return unmarshalFloat64Ptr
-		}
-		if slice {
-			return unmarshalFloat64Slice
-		}
-		return unmarshalFloat64Value
-	case reflect.Map:
-		panic("map type in typeUnmarshaler in " + t.Name())
-	case reflect.Slice:
-		if pointer {
-			panic("bad pointer in slice case in " + t.Name())
-		}
-		if slice {
-			return unmarshalBytesSlice
-		}
-		return unmarshalBytesValue
-	case reflect.String:
-		if validateUTF8 {
-			if pointer {
-				return unmarshalUTF8StringPtr
-			}
-			if slice {
-				return unmarshalUTF8StringSlice
-			}
-			return unmarshalUTF8StringValue
-		}
-		if pointer {
-			return unmarshalStringPtr
-		}
-		if slice {
-			return unmarshalStringSlice
-		}
-		return unmarshalStringValue
-	case reflect.Struct:
-		// message or group field
-		if !pointer {
-			panic(fmt.Sprintf("message/group field %s:%s without pointer", t, encoding))
-		}
-		switch encoding {
-		case "bytes":
-			if slice {
-				return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name)
-			}
-			return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name)
-		case "group":
-			if slice {
-				return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name)
-			}
-			return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name)
-		}
-	}
-	panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding))
-}
-
-// Below are all the unmarshalers for individual fields of various types.
-
-func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int64(x)
-	*f.toInt64() = v
-	return b, nil
-}
-
-func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int64(x)
-	*f.toInt64Ptr() = &v
-	return b, nil
-}
-
-func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			b = b[n:]
-			v := int64(x)
-			s := f.toInt64Slice()
-			*s = append(*s, v)
-		}
-		return res, nil
-	}
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int64(x)
-	s := f.toInt64Slice()
-	*s = append(*s, v)
-	return b, nil
-}
-
-func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int64(x>>1) ^ int64(x)<<63>>63
-	*f.toInt64() = v
-	return b, nil
-}
-
-func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int64(x>>1) ^ int64(x)<<63>>63
-	*f.toInt64Ptr() = &v
-	return b, nil
-}
-
-func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			b = b[n:]
-			v := int64(x>>1) ^ int64(x)<<63>>63
-			s := f.toInt64Slice()
-			*s = append(*s, v)
-		}
-		return res, nil
-	}
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int64(x>>1) ^ int64(x)<<63>>63
-	s := f.toInt64Slice()
-	*s = append(*s, v)
-	return b, nil
-}
-
-func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := uint64(x)
-	*f.toUint64() = v
-	return b, nil
-}
-
-func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := uint64(x)
-	*f.toUint64Ptr() = &v
-	return b, nil
-}
-
-func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			b = b[n:]
-			v := uint64(x)
-			s := f.toUint64Slice()
-			*s = append(*s, v)
-		}
-		return res, nil
-	}
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := uint64(x)
-	s := f.toUint64Slice()
-	*s = append(*s, v)
-	return b, nil
-}
-
-func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int32(x)
-	*f.toInt32() = v
-	return b, nil
-}
-
-func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int32(x)
-	f.setInt32Ptr(v)
-	return b, nil
-}
-
-func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			b = b[n:]
-			v := int32(x)
-			f.appendInt32Slice(v)
-		}
-		return res, nil
-	}
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int32(x)
-	f.appendInt32Slice(v)
-	return b, nil
-}
-
-func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int32(x>>1) ^ int32(x)<<31>>31
-	*f.toInt32() = v
-	return b, nil
-}
-
-func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int32(x>>1) ^ int32(x)<<31>>31
-	f.setInt32Ptr(v)
-	return b, nil
-}
-
-func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			b = b[n:]
-			v := int32(x>>1) ^ int32(x)<<31>>31
-			f.appendInt32Slice(v)
-		}
-		return res, nil
-	}
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := int32(x>>1) ^ int32(x)<<31>>31
-	f.appendInt32Slice(v)
-	return b, nil
-}
-
-func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := uint32(x)
-	*f.toUint32() = v
-	return b, nil
-}
-
-func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := uint32(x)
-	*f.toUint32Ptr() = &v
-	return b, nil
-}
-
-func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			b = b[n:]
-			v := uint32(x)
-			s := f.toUint32Slice()
-			*s = append(*s, v)
-		}
-		return res, nil
-	}
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	v := uint32(x)
-	s := f.toUint32Slice()
-	*s = append(*s, v)
-	return b, nil
-}
-
-func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
-	*f.toUint64() = v
-	return b[8:], nil
-}
-
-func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
-	*f.toUint64Ptr() = &v
-	return b[8:], nil
-}
-
-func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			if len(b) < 8 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
-			s := f.toUint64Slice()
-			*s = append(*s, v)
-			b = b[8:]
-		}
-		return res, nil
-	}
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
-	s := f.toUint64Slice()
-	*s = append(*s, v)
-	return b[8:], nil
-}
-
-func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
-	*f.toInt64() = v
-	return b[8:], nil
-}
-
-func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
-	*f.toInt64Ptr() = &v
-	return b[8:], nil
-}
-
-func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			if len(b) < 8 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
-			s := f.toInt64Slice()
-			*s = append(*s, v)
-			b = b[8:]
-		}
-		return res, nil
-	}
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
-	s := f.toInt64Slice()
-	*s = append(*s, v)
-	return b[8:], nil
-}
-
-func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
-	*f.toUint32() = v
-	return b[4:], nil
-}
-
-func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
-	*f.toUint32Ptr() = &v
-	return b[4:], nil
-}
-
-func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			if len(b) < 4 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
-			s := f.toUint32Slice()
-			*s = append(*s, v)
-			b = b[4:]
-		}
-		return res, nil
-	}
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
-	s := f.toUint32Slice()
-	*s = append(*s, v)
-	return b[4:], nil
-}
-
-func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
-	*f.toInt32() = v
-	return b[4:], nil
-}
-
-func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
-	f.setInt32Ptr(v)
-	return b[4:], nil
-}
-
-func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			if len(b) < 4 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
-			f.appendInt32Slice(v)
-			b = b[4:]
-		}
-		return res, nil
-	}
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
-	f.appendInt32Slice(v)
-	return b[4:], nil
-}
-
-func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	// Note: any length varint is allowed, even though any sane
-	// encoder will use one byte.
-	// See https://github.com/golang/protobuf/issues/76
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	// TODO: check if x>1? Tests seem to indicate no.
-	v := x != 0
-	*f.toBool() = v
-	return b[n:], nil
-}
-
-func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := x != 0
-	*f.toBoolPtr() = &v
-	return b[n:], nil
-}
-
-func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			x, n = decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			v := x != 0
-			s := f.toBoolSlice()
-			*s = append(*s, v)
-			b = b[n:]
-		}
-		return res, nil
-	}
-	if w != WireVarint {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := x != 0
-	s := f.toBoolSlice()
-	*s = append(*s, v)
-	return b[n:], nil
-}
-
-func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
-	*f.toFloat64() = v
-	return b[8:], nil
-}
-
-func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
-	*f.toFloat64Ptr() = &v
-	return b[8:], nil
-}
-
-func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			if len(b) < 8 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
-			s := f.toFloat64Slice()
-			*s = append(*s, v)
-			b = b[8:]
-		}
-		return res, nil
-	}
-	if w != WireFixed64 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 8 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
-	s := f.toFloat64Slice()
-	*s = append(*s, v)
-	return b[8:], nil
-}
-
-func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
-	*f.toFloat32() = v
-	return b[4:], nil
-}
-
-func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
-	*f.toFloat32Ptr() = &v
-	return b[4:], nil
-}
-
-func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) {
-	if w == WireBytes { // packed
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		res := b[x:]
-		b = b[:x]
-		for len(b) > 0 {
-			if len(b) < 4 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
-			s := f.toFloat32Slice()
-			*s = append(*s, v)
-			b = b[4:]
-		}
-		return res, nil
-	}
-	if w != WireFixed32 {
-		return b, errInternalBadWireType
-	}
-	if len(b) < 4 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
-	s := f.toFloat32Slice()
-	*s = append(*s, v)
-	return b[4:], nil
-}
-
-func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := string(b[:x])
-	*f.toString() = v
-	return b[x:], nil
-}
-
-func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := string(b[:x])
-	*f.toStringPtr() = &v
-	return b[x:], nil
-}
-
-func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := string(b[:x])
-	s := f.toStringSlice()
-	*s = append(*s, v)
-	return b[x:], nil
-}
-
-func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := string(b[:x])
-	*f.toString() = v
-	if !utf8.ValidString(v) {
-		return b[x:], errInvalidUTF8
-	}
-	return b[x:], nil
-}
-
-func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := string(b[:x])
-	*f.toStringPtr() = &v
-	if !utf8.ValidString(v) {
-		return b[x:], errInvalidUTF8
-	}
-	return b[x:], nil
-}
-
-func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := string(b[:x])
-	s := f.toStringSlice()
-	*s = append(*s, v)
-	if !utf8.ValidString(v) {
-		return b[x:], errInvalidUTF8
-	}
-	return b[x:], nil
-}
-
-var emptyBuf [0]byte
-
-func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	// The use of append here is a trick which avoids the zeroing
-	// that would be required if we used a make/copy pair.
-	// We append to emptyBuf instead of nil because we want
-	// a non-nil result even when the length is 0.
-	v := append(emptyBuf[:], b[:x]...)
-	*f.toBytes() = v
-	return b[x:], nil
-}
-
-func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) {
-	if w != WireBytes {
-		return b, errInternalBadWireType
-	}
-	x, n := decodeVarint(b)
-	if n == 0 {
-		return nil, io.ErrUnexpectedEOF
-	}
-	b = b[n:]
-	if x > uint64(len(b)) {
-		return nil, io.ErrUnexpectedEOF
-	}
-	v := append(emptyBuf[:], b[:x]...)
-	s := f.toBytesSlice()
-	*s = append(*s, v)
-	return b[x:], nil
-}
-
-func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler {
-	return func(b []byte, f pointer, w int) ([]byte, error) {
-		if w != WireBytes {
-			return b, errInternalBadWireType
-		}
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		// First read the message field to see if something is there.
-		// The semantics of multiple submessages are weird.  Instead of
-		// the last one winning (as it is for all other fields), multiple
-		// submessages are merged.
-		v := f.getPointer()
-		if v.isNil() {
-			v = valToPointer(reflect.New(sub.typ))
-			f.setPointer(v)
-		}
-		err := sub.unmarshal(v, b[:x])
-		if err != nil {
-			if r, ok := err.(*RequiredNotSetError); ok {
-				r.field = name + "." + r.field
-			} else {
-				return nil, err
-			}
-		}
-		return b[x:], err
-	}
-}
-
-func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler {
-	return func(b []byte, f pointer, w int) ([]byte, error) {
-		if w != WireBytes {
-			return b, errInternalBadWireType
-		}
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		v := valToPointer(reflect.New(sub.typ))
-		err := sub.unmarshal(v, b[:x])
-		if err != nil {
-			if r, ok := err.(*RequiredNotSetError); ok {
-				r.field = name + "." + r.field
-			} else {
-				return nil, err
-			}
-		}
-		f.appendPointer(v)
-		return b[x:], err
-	}
-}
-
-func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler {
-	return func(b []byte, f pointer, w int) ([]byte, error) {
-		if w != WireStartGroup {
-			return b, errInternalBadWireType
-		}
-		x, y := findEndGroup(b)
-		if x < 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		v := f.getPointer()
-		if v.isNil() {
-			v = valToPointer(reflect.New(sub.typ))
-			f.setPointer(v)
-		}
-		err := sub.unmarshal(v, b[:x])
-		if err != nil {
-			if r, ok := err.(*RequiredNotSetError); ok {
-				r.field = name + "." + r.field
-			} else {
-				return nil, err
-			}
-		}
-		return b[y:], err
-	}
-}
-
-func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler {
-	return func(b []byte, f pointer, w int) ([]byte, error) {
-		if w != WireStartGroup {
-			return b, errInternalBadWireType
-		}
-		x, y := findEndGroup(b)
-		if x < 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		v := valToPointer(reflect.New(sub.typ))
-		err := sub.unmarshal(v, b[:x])
-		if err != nil {
-			if r, ok := err.(*RequiredNotSetError); ok {
-				r.field = name + "." + r.field
-			} else {
-				return nil, err
-			}
-		}
-		f.appendPointer(v)
-		return b[y:], err
-	}
-}
-
-func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
-	t := f.Type
-	kt := t.Key()
-	vt := t.Elem()
-	unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key"))
-	unmarshalVal := typeUnmarshaler(vt, f.Tag.Get("protobuf_val"))
-	return func(b []byte, f pointer, w int) ([]byte, error) {
-		// The map entry is a submessage. Figure out how big it is.
-		if w != WireBytes {
-			return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes)
-		}
-		x, n := decodeVarint(b)
-		if n == 0 {
-			return nil, io.ErrUnexpectedEOF
-		}
-		b = b[n:]
-		if x > uint64(len(b)) {
-			return nil, io.ErrUnexpectedEOF
-		}
-		r := b[x:] // unused data to return
-		b = b[:x]  // data for map entry
-
-		// Note: we could use #keys * #values ~= 200 functions
-		// to do map decoding without reflection. Probably not worth it.
-		// Maps will be somewhat slow. Oh well.
-
-		// Read key and value from data.
-		var nerr nonFatal
-		k := reflect.New(kt)
-		v := reflect.New(vt)
-		for len(b) > 0 {
-			x, n := decodeVarint(b)
-			if n == 0 {
-				return nil, io.ErrUnexpectedEOF
-			}
-			wire := int(x) & 7
-			b = b[n:]
-
-			var err error
-			switch x >> 3 {
-			case 1:
-				b, err = unmarshalKey(b, valToPointer(k), wire)
-			case 2:
-				b, err = unmarshalVal(b, valToPointer(v), wire)
-			default:
-				err = errInternalBadWireType // skip unknown tag
-			}
-
-			if nerr.Merge(err) {
-				continue
-			}
-			if err != errInternalBadWireType {
-				return nil, err
-			}
-
-			// Skip past unknown fields.
-			b, err = skipField(b, wire)
-			if err != nil {
-				return nil, err
-			}
-		}
-
-		// Get map, allocate if needed.
-		m := f.asPointerTo(t).Elem() // an addressable map[K]T
-		if m.IsNil() {
-			m.Set(reflect.MakeMap(t))
-		}
-
-		// Insert into map.
-		m.SetMapIndex(k.Elem(), v.Elem())
-
-		return r, nerr.E
-	}
-}
-
-// makeUnmarshalOneof makes an unmarshaler for oneof fields.
-// for:
-// message Msg {
-//   oneof F {
-//     int64 X = 1;
-//     float64 Y = 2;
-//   }
-// }
-// typ is the type of the concrete entry for a oneof case (e.g. Msg_X).
-// ityp is the interface type of the oneof field (e.g. isMsg_F).
-// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64).
-// Note that this function will be called once for each case in the oneof.
-func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler {
-	sf := typ.Field(0)
-	field0 := toField(&sf)
-	return func(b []byte, f pointer, w int) ([]byte, error) {
-		// Allocate holder for value.
-		v := reflect.New(typ)
-
-		// Unmarshal data into holder.
-		// We unmarshal into the first field of the holder object.
-		var err error
-		var nerr nonFatal
-		b, err = unmarshal(b, valToPointer(v).offset(field0), w)
-		if !nerr.Merge(err) {
-			return nil, err
-		}
-
-		// Write pointer to holder into target field.
-		f.asPointerTo(ityp).Elem().Set(v)
-
-		return b, nerr.E
-	}
-}
-
-// Error used by decode internally.
-var errInternalBadWireType = errors.New("proto: internal error: bad wiretype")
-
-// skipField skips past a field of type wire and returns the remaining bytes.
-func skipField(b []byte, wire int) ([]byte, error) {
-	switch wire {
-	case WireVarint:
-		_, k := decodeVarint(b)
-		if k == 0 {
-			return b, io.ErrUnexpectedEOF
-		}
-		b = b[k:]
-	case WireFixed32:
-		if len(b) < 4 {
-			return b, io.ErrUnexpectedEOF
-		}
-		b = b[4:]
-	case WireFixed64:
-		if len(b) < 8 {
-			return b, io.ErrUnexpectedEOF
-		}
-		b = b[8:]
-	case WireBytes:
-		m, k := decodeVarint(b)
-		if k == 0 || uint64(len(b)-k) < m {
-			return b, io.ErrUnexpectedEOF
-		}
-		b = b[uint64(k)+m:]
-	case WireStartGroup:
-		_, i := findEndGroup(b)
-		if i == -1 {
-			return b, io.ErrUnexpectedEOF
-		}
-		b = b[i:]
-	default:
-		return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire)
-	}
-	return b, nil
-}
-
-// findEndGroup finds the index of the next EndGroup tag.
-// Groups may be nested, so the "next" EndGroup tag is the first
-// unpaired EndGroup.
-// findEndGroup returns the indexes of the start and end of the EndGroup tag.
-// Returns (-1,-1) if it can't find one.
-func findEndGroup(b []byte) (int, int) {
-	depth := 1
-	i := 0
-	for {
-		x, n := decodeVarint(b[i:])
-		if n == 0 {
-			return -1, -1
-		}
-		j := i
-		i += n
-		switch x & 7 {
-		case WireVarint:
-			_, k := decodeVarint(b[i:])
-			if k == 0 {
-				return -1, -1
-			}
-			i += k
-		case WireFixed32:
-			if len(b)-4 < i {
-				return -1, -1
-			}
-			i += 4
-		case WireFixed64:
-			if len(b)-8 < i {
-				return -1, -1
-			}
-			i += 8
-		case WireBytes:
-			m, k := decodeVarint(b[i:])
-			if k == 0 {
-				return -1, -1
-			}
-			i += k
-			if uint64(len(b)-i) < m {
-				return -1, -1
-			}
-			i += int(m)
-		case WireStartGroup:
-			depth++
-		case WireEndGroup:
-			depth--
-			if depth == 0 {
-				return j, i
-			}
-		default:
-			return -1, -1
-		}
-	}
-}
-
-// encodeVarint appends a varint-encoded integer to b and returns the result.
-func encodeVarint(b []byte, x uint64) []byte {
-	for x >= 1<<7 {
-		b = append(b, byte(x&0x7f|0x80))
-		x >>= 7
-	}
-	return append(b, byte(x))
-}
-
-// decodeVarint reads a varint-encoded integer from b.
-// Returns the decoded integer and the number of bytes read.
-// If there is an error, it returns 0,0.
-func decodeVarint(b []byte) (uint64, int) {
-	var x, y uint64
-	if len(b) <= 0 {
-		goto bad
-	}
-	x = uint64(b[0])
-	if x < 0x80 {
-		return x, 1
-	}
-	x -= 0x80
-
-	if len(b) <= 1 {
-		goto bad
-	}
-	y = uint64(b[1])
-	x += y << 7
-	if y < 0x80 {
-		return x, 2
-	}
-	x -= 0x80 << 7
-
-	if len(b) <= 2 {
-		goto bad
-	}
-	y = uint64(b[2])
-	x += y << 14
-	if y < 0x80 {
-		return x, 3
-	}
-	x -= 0x80 << 14
-
-	if len(b) <= 3 {
-		goto bad
-	}
-	y = uint64(b[3])
-	x += y << 21
-	if y < 0x80 {
-		return x, 4
-	}
-	x -= 0x80 << 21
-
-	if len(b) <= 4 {
-		goto bad
-	}
-	y = uint64(b[4])
-	x += y << 28
-	if y < 0x80 {
-		return x, 5
-	}
-	x -= 0x80 << 28
-
-	if len(b) <= 5 {
-		goto bad
-	}
-	y = uint64(b[5])
-	x += y << 35
-	if y < 0x80 {
-		return x, 6
-	}
-	x -= 0x80 << 35
-
-	if len(b) <= 6 {
-		goto bad
-	}
-	y = uint64(b[6])
-	x += y << 42
-	if y < 0x80 {
-		return x, 7
-	}
-	x -= 0x80 << 42
-
-	if len(b) <= 7 {
-		goto bad
-	}
-	y = uint64(b[7])
-	x += y << 49
-	if y < 0x80 {
-		return x, 8
-	}
-	x -= 0x80 << 49
-
-	if len(b) <= 8 {
-		goto bad
-	}
-	y = uint64(b[8])
-	x += y << 56
-	if y < 0x80 {
-		return x, 9
-	}
-	x -= 0x80 << 56
-
-	if len(b) <= 9 {
-		goto bad
-	}
-	y = uint64(b[9])
-	x += y << 63
-	if y < 2 {
-		return x, 10
-	}
-
-bad:
-	return 0, 0
-}
diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go
index 1aaee725b..965876bf0 100644
--- a/vendor/github.com/golang/protobuf/proto/text.go
+++ b/vendor/github.com/golang/protobuf/proto/text.go
@@ -50,6 +50,7 @@ import (
 var (
 	newline         = []byte("\n")
 	spaces          = []byte("                                        ")
+	gtNewline       = []byte(">\n")
 	endBraceNewline = []byte("}\n")
 	backslashN      = []byte{'\\', 'n'}
 	backslashR      = []byte{'\\', 'r'}
@@ -169,6 +170,11 @@ func writeName(w *textWriter, props *Properties) error {
 	return nil
 }
 
+// raw is the interface satisfied by RawMessage.
+type raw interface {
+	Bytes() []byte
+}
+
 func requiresQuotes(u string) bool {
 	// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
 	for _, ch := range u {
@@ -263,10 +269,6 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 		props := sprops.Prop[i]
 		name := st.Field(i).Name
 
-		if name == "XXX_NoUnkeyedLiteral" {
-			continue
-		}
-
 		if strings.HasPrefix(name, "XXX_") {
 			// There are two XXX_ fields:
 			//   XXX_unrecognized []byte
@@ -353,7 +355,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 						return err
 					}
 				}
-				if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
+				if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
 					return err
 				}
 				if err := w.WriteByte('\n'); err != nil {
@@ -370,7 +372,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 							return err
 						}
 					}
-					if err := tm.writeAny(w, val, props.MapValProp); err != nil {
+					if err := tm.writeAny(w, val, props.mvalprop); err != nil {
 						return err
 					}
 					if err := w.WriteByte('\n'); err != nil {
@@ -434,6 +436,12 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 				return err
 			}
 		}
+		if b, ok := fv.Interface().(raw); ok {
+			if err := writeRaw(w, b.Bytes()); err != nil {
+				return err
+			}
+			continue
+		}
 
 		// Enums have a String method, so writeAny will work fine.
 		if err := tm.writeAny(w, fv, props); err != nil {
@@ -447,7 +455,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 
 	// Extensions (the XXX_extensions field).
 	pv := sv.Addr()
-	if _, err := extendable(pv.Interface()); err == nil {
+	if _, ok := extendable(pv.Interface()); ok {
 		if err := tm.writeExtensions(w, pv); err != nil {
 			return err
 		}
@@ -456,6 +464,27 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 	return nil
 }
 
+// writeRaw writes an uninterpreted raw message.
+func writeRaw(w *textWriter, b []byte) error {
+	if err := w.WriteByte('<'); err != nil {
+		return err
+	}
+	if !w.compact {
+		if err := w.WriteByte('\n'); err != nil {
+			return err
+		}
+	}
+	w.indent()
+	if err := writeUnknownStruct(w, b); err != nil {
+		return err
+	}
+	w.unindent()
+	if err := w.WriteByte('>'); err != nil {
+		return err
+	}
+	return nil
+}
+
 // writeAny writes an arbitrary field.
 func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
 	v = reflect.Indirect(v)
@@ -506,19 +535,6 @@ func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Propert
 			}
 		}
 		w.indent()
-		if v.CanAddr() {
-			// Calling v.Interface on a struct causes the reflect package to
-			// copy the entire struct. This is racy with the new Marshaler
-			// since we atomically update the XXX_sizecache.
-			//
-			// Thus, we retrieve a pointer to the struct if possible to avoid
-			// a race since v.Interface on the pointer doesn't copy the struct.
-			//
-			// If v is not addressable, then we are not worried about a race
-			// since it implies that the binary Marshaler cannot possibly be
-			// mutating this value.
-			v = v.Addr()
-		}
 		if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
 			text, err := etm.MarshalText()
 			if err != nil {
@@ -527,13 +543,8 @@ func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Propert
 			if _, err = w.Write(text); err != nil {
 				return err
 			}
-		} else {
-			if v.Kind() == reflect.Ptr {
-				v = v.Elem()
-			}
-			if err := tm.writeStruct(w, v); err != nil {
-				return err
-			}
+		} else if err := tm.writeStruct(w, v); err != nil {
+			return err
 		}
 		w.unindent()
 		if err := w.WriteByte(ket); err != nil {
diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go
index bb55a3af2..61f83c1e1 100644
--- a/vendor/github.com/golang/protobuf/proto/text_parser.go
+++ b/vendor/github.com/golang/protobuf/proto/text_parser.go
@@ -206,6 +206,7 @@ func (p *textParser) advance() {
 
 var (
 	errBadUTF8 = errors.New("proto: bad UTF-8")
+	errBadHex  = errors.New("proto: bad hexadecimal")
 )
 
 func unquoteC(s string, quote rune) (string, error) {
@@ -276,47 +277,60 @@ func unescape(s string) (ch string, tail string, err error) {
 		return "?", s, nil // trigraph workaround
 	case '\'', '"', '\\':
 		return string(r), s, nil
-	case '0', '1', '2', '3', '4', '5', '6', '7':
+	case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
 		if len(s) < 2 {
 			return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
 		}
-		ss := string(r) + s[:2]
+		base := 8
+		ss := s[:2]
 		s = s[2:]
-		i, err := strconv.ParseUint(ss, 8, 8)
+		if r == 'x' || r == 'X' {
+			base = 16
+		} else {
+			ss = string(r) + ss
+		}
+		i, err := strconv.ParseUint(ss, base, 8)
 		if err != nil {
-			return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss)
+			return "", "", err
 		}
 		return string([]byte{byte(i)}), s, nil
-	case 'x', 'X', 'u', 'U':
-		var n int
-		switch r {
-		case 'x', 'X':
-			n = 2
-		case 'u':
-			n = 4
-		case 'U':
+	case 'u', 'U':
+		n := 4
+		if r == 'U' {
 			n = 8
 		}
 		if len(s) < n {
-			return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n)
-		}
-		ss := s[:n]
-		s = s[n:]
-		i, err := strconv.ParseUint(ss, 16, 64)
-		if err != nil {
-			return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss)
-		}
-		if r == 'x' || r == 'X' {
-			return string([]byte{byte(i)}), s, nil
+			return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
 		}
-		if i > utf8.MaxRune {
-			return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
+
+		bs := make([]byte, n/2)
+		for i := 0; i < n; i += 2 {
+			a, ok1 := unhex(s[i])
+			b, ok2 := unhex(s[i+1])
+			if !ok1 || !ok2 {
+				return "", "", errBadHex
+			}
+			bs[i/2] = a<<4 | b
 		}
-		return string(i), s, nil
+		s = s[n:]
+		return string(bs), s, nil
 	}
 	return "", "", fmt.Errorf(`unknown escape \%c`, r)
 }
 
+// Adapted from src/pkg/strconv/quote.go.
+func unhex(b byte) (v byte, ok bool) {
+	switch {
+	case '0' <= b && b <= '9':
+		return b - '0', true
+	case 'a' <= b && b <= 'f':
+		return b - 'a' + 10, true
+	case 'A' <= b && b <= 'F':
+		return b - 'A' + 10, true
+	}
+	return 0, false
+}
+
 // Back off the parser by one token. Can only be done between calls to next().
 // It makes the next advance() a no-op.
 func (p *textParser) back() { p.backed = true }
@@ -630,17 +644,17 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 					if err := p.consumeToken(":"); err != nil {
 						return err
 					}
-					if err := p.readAny(key, props.MapKeyProp); err != nil {
+					if err := p.readAny(key, props.mkeyprop); err != nil {
 						return err
 					}
 					if err := p.consumeOptionalSeparator(); err != nil {
 						return err
 					}
 				case "value":
-					if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil {
+					if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
 						return err
 					}
-					if err := p.readAny(val, props.MapValProp); err != nil {
+					if err := p.readAny(val, props.mvalprop); err != nil {
 						return err
 					}
 					if err := p.consumeOptionalSeparator(); err != nil {
@@ -714,9 +728,6 @@ func (p *textParser) consumeExtName() (string, error) {
 		if tok.err != nil {
 			return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
 		}
-		if p.done && tok.value != "]" {
-			return "", p.errorf("unclosed type_url or extension name")
-		}
 	}
 	return strings.Join(parts, ""), nil
 }
@@ -872,9 +883,13 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 // UnmarshalText returns *RequiredNotSetError.
 func UnmarshalText(s string, pb Message) error {
 	if um, ok := pb.(encoding.TextUnmarshaler); ok {
-		return um.UnmarshalText([]byte(s))
+		err := um.UnmarshalText([]byte(s))
+		return err
 	}
 	pb.Reset()
 	v := reflect.ValueOf(pb)
-	return newTextParser(s).readStruct(v.Elem(), "")
+	if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
+		return pe
+	}
+	return nil
 }
diff --git a/vendor/github.com/googollee/go-engine.io/.travis.yml b/vendor/github.com/googollee/go-engine.io/.travis.yml
new file mode 100644
index 000000000..0a5134f0d
--- /dev/null
+++ b/vendor/github.com/googollee/go-engine.io/.travis.yml
@@ -0,0 +1,7 @@
+language: go
+go: 1.5
+install:
+  - go get "github.com/smartystreets/goconvey/convey"
+  - go get -v .
+script:
+  - go test -race -v ./...
diff --git a/vendor/github.com/googollee/go-engine.io/README.md b/vendor/github.com/googollee/go-engine.io/README.md
new file mode 100644
index 000000000..c5d603f57
--- /dev/null
+++ b/vendor/github.com/googollee/go-engine.io/README.md
@@ -0,0 +1,78 @@
+# go-engine.io
+
+[![GoDoc](http://godoc.org/github.com/googollee/go-engine.io?status.svg)](http://godoc.org/github.com/googollee/go-engine.io) [![Build Status](https://travis-ci.org/googollee/go-engine.io.svg)](https://travis-ci.org/googollee/go-engine.io)
+
+go-engine.io is the implement of engine.io in golang, which is transport-based cross-browser/cross-device bi-directional communication layer for [go-socket.io](https://github.com/googollee/go-socket.io).
+
+It is compatible with node.js implement, and supported long-polling and websocket transport.
+
+## Install
+
+Install the package with:
+
+```bash
+go get github.com/googollee/go-engine.io
+```
+
+Import it with:
+
+```go
+import "github.com/googollee/go-engine.io"
+```
+
+and use `engineio` as the package name inside the code.
+
+## Example
+
+Please check example folder for details.
+
+```go
+package main
+
+import (
+	"encoding/hex"
+	"io/ioutil"
+	"log"
+	"net/http"
+
+	"github.com/googollee/go-engine.io"
+)
+
+func main() {
+	server, err := engineio.NewServer(nil)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	go func() {
+		for {
+			conn, _ := server.Accept()
+			go func() {
+				defer conn.Close()
+				for i := 0; i < 10; i++ {
+					t, r, _ := conn.NextReader()
+					b, _ := ioutil.ReadAll(r)
+					r.Close()
+					if t == engineio.MessageText {
+						log.Println(t, string(b))
+					} else {
+						log.Println(t, hex.EncodeToString(b))
+					}
+					w, _ := conn.NextWriter(t)
+					w.Write([]byte("pong"))
+					w.Close()
+				}
+			}()
+		}
+	}()
+
+	http.Handle("/engine.io/", server)
+	http.Handle("/", http.FileServer(http.Dir("./asset")))
+	log.Println("Serving at localhost:5000...")
+	log.Fatal(http.ListenAndServe(":5000", nil))
+}
+```
+
+## License
+
+The 3-clause BSD License  - see LICENSE for more details
\ No newline at end of file
diff --git a/vendor/github.com/googollee/go-socket.io/.gitignore b/vendor/github.com/googollee/go-socket.io/.gitignore
new file mode 100644
index 000000000..615566c1e
--- /dev/null
+++ b/vendor/github.com/googollee/go-socket.io/.gitignore
@@ -0,0 +1,4 @@
+
+.DS_Store
+.idea/
+go.sum
\ No newline at end of file
diff --git a/vendor/github.com/googollee/go-socket.io/.travis.yml b/vendor/github.com/googollee/go-socket.io/.travis.yml
new file mode 100644
index 000000000..ca7753f3d
--- /dev/null
+++ b/vendor/github.com/googollee/go-socket.io/.travis.yml
@@ -0,0 +1,7 @@
+language: go
+go:
+- 1.7.x
+- 1.11.x
+install:
+  - go get "github.com/smartystreets/goconvey/convey"
+  - go get -v .
diff --git a/vendor/github.com/googollee/go-socket.io/README.md b/vendor/github.com/googollee/go-socket.io/README.md
new file mode 100644
index 000000000..e5a160ddd
--- /dev/null
+++ b/vendor/github.com/googollee/go-socket.io/README.md
@@ -0,0 +1,127 @@
+# socket.io
+
+[![GoDoc](http://godoc.org/github.com/googollee/go-socket.io?status.svg)](http://godoc.org/github.com/googollee/go-socket.io) [![Build Status](https://travis-ci.org/googollee/go-socket.io.svg)](https://travis-ci.org/googollee/go-socket.io)
+
+**Please use v1.4 branch, or import "gopkg.in/googollee/go-socket.io.v1". I have no time to maintain master branch now**
+
+go-socket.io is an implementation of [socket.io](http://socket.io) in golang, which is a realtime application framework.
+
+It is compatible with latest implementation of socket.io in node.js, and supports room and namespace.
+
+* for compatability with socket.io 0.9.x, please use branch 0.9.x *
+
+## Install
+
+Install the package with:
+
+```bash
+go get github.com/googollee/go-socket.io
+```
+
+Import it with:
+
+```go
+import "github.com/googollee/go-socket.io"
+```
+
+and use `socketio` as the package name inside the code.
+
+## Example
+
+Please check the example folder for details.
+
+```go
+package main
+
+import (
+	"log"
+	"net/http"
+
+	"github.com/googollee/go-socket.io"
+)
+
+func main() {
+	server, err := socketio.NewServer(nil)
+	if err != nil {
+		log.Fatal(err)
+	}
+	server.On("connection", func(so socketio.Socket) {
+		log.Println("on connection")
+		so.Join("chat")
+		so.On("chat message", func(msg string) {
+			log.Println("emit:", so.Emit("chat message", msg))
+			so.BroadcastTo("chat", "chat message", msg)
+		})
+		so.On("disconnection", func() {
+			log.Println("on disconnect")
+		})
+	})
+	server.On("error", func(so socketio.Socket, err error) {
+		log.Println("error:", err)
+	})
+
+	http.Handle("/socket.io/", server)
+	http.Handle("/", http.FileServer(http.Dir("./asset")))
+	log.Println("Serving at localhost:5000...")
+	log.Fatal(http.ListenAndServe(":5000", nil))
+}
+```
+
+## Acknowledgements in go-socket.io 1.X.X
+
+[See documentation about acknowledgements](http://socket.io/docs/#sending-and-getting-data-(acknowledgements))
+
+##### Sending ACK with data from SERVER to CLIENT
+
+* Client-side
+
+```javascript
+ //using client-side socket.io-1.X.X.js
+ socket.emit('some:event', JSON.stringify(someData), function(data){
+       console.log('ACK from server wtih data: ', data));
+ });
+```
+
+* Server-side
+
+```go
+// The return type may vary depending on whether you will return
+// In golang implementation of socket.io don't used callbacks for acknowledgement,
+// but used return value, which wrapped into ack package and returned to the client's callback in JavaScript
+so.On("some:event", func(msg string) string {
+	return msg //Sending ack with data in msg back to client, using "return statement"
+})
+```
+
+##### Sending ACK with data from CLIENT to SERVER
+
+* Client-side
+
+```javascript
+//using client-side socket.io-1.X.X.js
+//last parameter of "on" handler is callback for sending ack to server with data or without data
+socket.on('some:event', function (msg, sendAckCb) {
+    //Sending ACK with data to server after receiving some:event from server
+    sendAckCb(JSON.stringify(data)); // for example used serializing to JSON
+}
+```
+
+* Server-side
+
+```go
+//You can use Emit or BroadcastTo with last parameter as callback for handling ack from client
+//Sending packet to room "room_name" and event "some:event"
+so.BroadcastTo("room_name", "some:event", dataForClient, func (so socketio.Socket, data string) {
+	log.Println("Client ACK with data: ", data)
+})
+
+// Or
+
+so.Emit("some:event", dataForClient, func (so socketio.Socket, data string) {
+	log.Println("Client ACK with data: ", data)
+})
+```
+
+## License
+
+The 3-clause BSD License  - see LICENSE for more details
diff --git a/vendor/github.com/gorilla/websocket/.gitignore b/vendor/github.com/gorilla/websocket/.gitignore
new file mode 100644
index 000000000..cd3fcd1ef
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/.gitignore
@@ -0,0 +1,25 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+
+.idea/
+*.iml
diff --git a/vendor/github.com/gorilla/websocket/.travis.yml b/vendor/github.com/gorilla/websocket/.travis.yml
new file mode 100644
index 000000000..a49db51c4
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/.travis.yml
@@ -0,0 +1,19 @@
+language: go
+sudo: false
+
+matrix:
+  include:
+    - go: 1.7.x
+    - go: 1.8.x
+    - go: 1.9.x
+    - go: 1.10.x
+    - go: 1.11.x
+    - go: tip
+  allow_failures:
+    - go: tip
+
+script:
+  - go get -t -v ./...
+  - diff -u <(echo -n) <(gofmt -d .)
+  - go vet $(go list ./... | grep -v /vendor/)
+  - go test -v -race ./...
diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md
new file mode 100644
index 000000000..20e391f86
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/README.md
@@ -0,0 +1,64 @@
+# Gorilla WebSocket
+
+Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
+[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
+
+[![Build Status](https://travis-ci.org/gorilla/websocket.svg?branch=master)](https://travis-ci.org/gorilla/websocket)
+[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
+
+### Documentation
+
+* [API Reference](http://godoc.org/github.com/gorilla/websocket)
+* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
+* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
+* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
+* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
+
+### Status
+
+The Gorilla WebSocket package provides a complete and tested implementation of
+the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
+package API is stable.
+
+### Installation
+
+    go get github.com/gorilla/websocket
+
+### Protocol Compliance
+
+The Gorilla WebSocket package passes the server tests in the [Autobahn Test
+Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
+subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
+
+### Gorilla WebSocket compared with other packages
+
+<table>
+<tr>
+<th></th>
+<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
+<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
+</tr>
+<tr>
+<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
+<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
+<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
+<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
+<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
+<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
+<tr><td colspan="3">Other Features</tr></td>
+<tr><td><a href="https://tools.ietf.org/html/rfc7692">Compression Extensions</a></td><td>Experimental</td><td>No</td></tr>
+<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
+<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
+</table>
+
+Notes:
+
+1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
+2. The application can get the type of a received data message by implementing
+   a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
+   function.
+3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
+  Read returns when the input buffer is full or a frame boundary is
+  encountered. Each call to Write sends a single frame message. The Gorilla
+  io.Reader and io.WriteCloser operate on a single WebSocket message.
+
diff --git a/vendor/github.com/itsjamie/gin-cors/.gitignore b/vendor/github.com/itsjamie/gin-cors/.gitignore
new file mode 100644
index 000000000..daf913b1b
--- /dev/null
+++ b/vendor/github.com/itsjamie/gin-cors/.gitignore
@@ -0,0 +1,24 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
diff --git a/vendor/github.com/itsjamie/gin-cors/.travis.yml b/vendor/github.com/itsjamie/gin-cors/.travis.yml
new file mode 100644
index 000000000..2124b2f29
--- /dev/null
+++ b/vendor/github.com/itsjamie/gin-cors/.travis.yml
@@ -0,0 +1,10 @@
+language: go
+
+go:
+    - tip
+before_install:
+    - go get github.com/axw/gocov/gocov
+    - go get github.com/mattn/goveralls
+    - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
+script:
+    - $HOME/gopath/bin/goveralls -service=travis-ci
\ No newline at end of file
diff --git a/vendor/github.com/itsjamie/gin-cors/README.md b/vendor/github.com/itsjamie/gin-cors/README.md
new file mode 100644
index 000000000..f5693fc93
--- /dev/null
+++ b/vendor/github.com/itsjamie/gin-cors/README.md
@@ -0,0 +1,50 @@
+# CORS for Gin [![GoDoc](https://godoc.org/github.com/itsjamie/gin-cors?status.svg)](https://godoc.org/github.com/itsjamie/gin-cors) [![Build Status](https://travis-ci.org/itsjamie/gin-cors.svg?branch=master)](https://travis-ci.org/itsjamie/gin-cors) [![Coverage Status](https://coveralls.io/repos/itsjamie/gin-cors/badge.svg?branch=master)](https://coveralls.io/r/itsjamie/gin-cors?branch=master)
+
+gin-cors is a middleware written in [Go (Golang)](http://golang.org) specifically for the [Gin Framework](https://gin-gonic.github.io/gin/) that implements the [Cross Origin Resource Sharing specification](http://www.w3.org/TR/cors/) from the W3C.  Implementing CORS headers enable pages within a modern web browser to consume resources (such as REST APIs) from servers that are on a different domain.
+
+## Getting Started
+To use this library, add the following code into your Gin router setup:
+
+```go
+import "github.com/itsjamie/gin-cors"
+
+// Initialize a new Gin router
+router := gin.New()
+
+// Apply the middleware to the router (works with groups too)
+router.Use(cors.Middleware(cors.Config{
+	Origins:        "*",
+	Methods:        "GET, PUT, POST, DELETE",
+	RequestHeaders: "Origin, Authorization, Content-Type",
+	ExposedHeaders: "",
+	MaxAge: 50 * time.Second,
+	Credentials: true,
+	ValidateHeaders: false,
+}))
+```
+
+## Setup Options
+The middleware can be configured with four options, which match the HTTP headers that it generates:
+
+Parameter          | Type            | Details
+-------------------|-----------------|----------------------------------
+Origins            | *string*        | A comma delimited list of origins which have access. For example: ```"http://localhost, http://api.server.com, http://files.server.com"```
+RequestHeaders     | *string*        | A comma delimited list of allowed HTTP  that is passed to the browser in the **Access-Control-Allow-Headers** header.
+ExposeHeaders      | *string*        | A comma delimited list of HTTP headers that should be exposed to the CORS client via the **Access-Control-Expose-Headers** header.
+Methods            | *string*        | A comma delimited list of allowed HTTP methods that is passed to the browser in the **Access-Control-Allow-Methods**.
+MaxAge             | *time.Duration* | The amount of time a preflight request should be cached, if not specified, the header **Access-Control-Max-Age** will not be set.
+Credentials        | *bool*          | This is passed in the **Access-Control-Allow-Credentials** header. If ```true``` Cookies, HTTP authentication and the client-side SSL certificates will be sent on previous interactions with the origin.
+ValidateHeaders    | *bool*          | If ```false``` we skip validating the requested headers/methods with the list of allowed ones, and instead just respond with all what we support, it is up to the client implementating CORS to deny the request. This is an optimization allowed by the specification. 
+
+
+## CORS Resources
+
+* [HTML Rocks Tutorial: Using CORS](http://www.html5rocks.com/en/tutorials/cors/)
+* [Mozilla Developer Network: CORS Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
+* [CORS Specification from W3C](http://www.w3.org/TR/cors/)
+
+## Special Thanks
+Special thanks to [benpate](https://github.com/benpate) for providing a foundation to work from.
+
+## License
+The code is licensed under the MIT License. See LICENSE file for more details.
diff --git a/vendor/github.com/json-iterator/go/.codecov.yml b/vendor/github.com/json-iterator/go/.codecov.yml
new file mode 100644
index 000000000..955dc0be5
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/.codecov.yml
@@ -0,0 +1,3 @@
+ignore:
+    - "output_tests/.*"
+
diff --git a/vendor/github.com/json-iterator/go/.gitignore b/vendor/github.com/json-iterator/go/.gitignore
new file mode 100644
index 000000000..501fcdc9a
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/.gitignore
@@ -0,0 +1,3 @@
+.idea
+/coverage.txt
+/profile.out
diff --git a/vendor/github.com/json-iterator/go/.travis.yml b/vendor/github.com/json-iterator/go/.travis.yml
new file mode 100644
index 000000000..945b9c594
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/.travis.yml
@@ -0,0 +1,13 @@
+language: go
+
+go:
+  - 1.8.x
+
+before_install:
+  - go get -t -v ./...
+
+script:
+  - ./test.sh
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md
new file mode 100644
index 000000000..23a4b57c8
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/README.md
@@ -0,0 +1,80 @@
+[![Sourcegraph](https://sourcegraph.com/github.com/json-iterator/go/-/badge.svg)](https://sourcegraph.com/github.com/json-iterator/go?badge)
+[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/json-iterator/go)
+[![Build Status](https://travis-ci.org/json-iterator/go.svg?branch=master)](https://travis-ci.org/json-iterator/go)
+[![codecov](https://codecov.io/gh/json-iterator/go/branch/master/graph/badge.svg)](https://codecov.io/gh/json-iterator/go)
+[![rcard](https://goreportcard.com/badge/github.com/json-iterator/go)](https://goreportcard.com/report/github.com/json-iterator/go)
+[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE)
+[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby)
+
+A high-performance 100% compatible drop-in replacement of "encoding/json"
+
+```
+Go开发者们请加入我们,滴滴出行平台技术部 taowen@didichuxing.com
+```
+
+# Benchmark
+
+![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png)
+
+Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go
+
+Raw Result (easyjson requires static code generation)
+
+| | ns/op | allocation bytes | allocation times |
+| --- | --- | --- | --- |
+| std decode | 35510 ns/op | 1960 B/op | 99 allocs/op |
+| easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op |
+| jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op |
+| std encode | 2213 ns/op | 712 B/op | 5 allocs/op |
+| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op |
+| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op |
+
+# Usage
+
+100% compatibility with standard lib
+
+Replace
+
+```go
+import "encoding/json"
+json.Marshal(&data)
+```
+
+with 
+
+```go
+import "github.com/json-iterator/go"
+jsoniter.Marshal(&data)
+```
+
+Replace
+
+```go
+import "encoding/json"
+json.Unmarshal(input, &data)
+```
+
+with
+
+```go
+import "github.com/json-iterator/go"
+jsoniter.Unmarshal(input, &data)
+```
+
+[More documentation](http://jsoniter.com/migrate-from-go-std.html)
+
+# How to get
+
+```
+go get github.com/json-iterator/go
+```
+
+# Contribution Welcomed !
+
+Contributors
+
+* [thockin](https://github.com/thockin) 
+* [mattn](https://github.com/mattn)
+* [cch123](https://github.com/cch123)
+
+Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby)
diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go
deleted file mode 100644
index 8c58fcba5..000000000
--- a/vendor/github.com/json-iterator/go/config.go
+++ /dev/null
@@ -1,375 +0,0 @@
-package jsoniter
-
-import (
-	"encoding/json"
-	"io"
-	"reflect"
-	"sync"
-	"unsafe"
-
-	"github.com/modern-go/concurrent"
-	"github.com/modern-go/reflect2"
-)
-
-// Config customize how the API should behave.
-// The API is created from Config by Froze.
-type Config struct {
-	IndentionStep                 int
-	MarshalFloatWith6Digits       bool
-	EscapeHTML                    bool
-	SortMapKeys                   bool
-	UseNumber                     bool
-	DisallowUnknownFields         bool
-	TagKey                        string
-	OnlyTaggedField               bool
-	ValidateJsonRawMessage        bool
-	ObjectFieldMustBeSimpleString bool
-	CaseSensitive                 bool
-}
-
-// API the public interface of this package.
-// Primary Marshal and Unmarshal.
-type API interface {
-	IteratorPool
-	StreamPool
-	MarshalToString(v interface{}) (string, error)
-	Marshal(v interface{}) ([]byte, error)
-	MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
-	UnmarshalFromString(str string, v interface{}) error
-	Unmarshal(data []byte, v interface{}) error
-	Get(data []byte, path ...interface{}) Any
-	NewEncoder(writer io.Writer) *Encoder
-	NewDecoder(reader io.Reader) *Decoder
-	Valid(data []byte) bool
-	RegisterExtension(extension Extension)
-	DecoderOf(typ reflect2.Type) ValDecoder
-	EncoderOf(typ reflect2.Type) ValEncoder
-}
-
-// ConfigDefault the default API
-var ConfigDefault = Config{
-	EscapeHTML: true,
-}.Froze()
-
-// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
-var ConfigCompatibleWithStandardLibrary = Config{
-	EscapeHTML:             true,
-	SortMapKeys:            true,
-	ValidateJsonRawMessage: true,
-}.Froze()
-
-// ConfigFastest marshals float with only 6 digits precision
-var ConfigFastest = Config{
-	EscapeHTML:                    false,
-	MarshalFloatWith6Digits:       true, // will lose precession
-	ObjectFieldMustBeSimpleString: true, // do not unescape object field
-}.Froze()
-
-type frozenConfig struct {
-	configBeforeFrozen            Config
-	sortMapKeys                   bool
-	indentionStep                 int
-	objectFieldMustBeSimpleString bool
-	onlyTaggedField               bool
-	disallowUnknownFields         bool
-	decoderCache                  *concurrent.Map
-	encoderCache                  *concurrent.Map
-	encoderExtension              Extension
-	decoderExtension              Extension
-	extraExtensions               []Extension
-	streamPool                    *sync.Pool
-	iteratorPool                  *sync.Pool
-	caseSensitive                 bool
-}
-
-func (cfg *frozenConfig) initCache() {
-	cfg.decoderCache = concurrent.NewMap()
-	cfg.encoderCache = concurrent.NewMap()
-}
-
-func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
-	cfg.decoderCache.Store(cacheKey, decoder)
-}
-
-func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
-	cfg.encoderCache.Store(cacheKey, encoder)
-}
-
-func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
-	decoder, found := cfg.decoderCache.Load(cacheKey)
-	if found {
-		return decoder.(ValDecoder)
-	}
-	return nil
-}
-
-func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
-	encoder, found := cfg.encoderCache.Load(cacheKey)
-	if found {
-		return encoder.(ValEncoder)
-	}
-	return nil
-}
-
-var cfgCache = concurrent.NewMap()
-
-func getFrozenConfigFromCache(cfg Config) *frozenConfig {
-	obj, found := cfgCache.Load(cfg)
-	if found {
-		return obj.(*frozenConfig)
-	}
-	return nil
-}
-
-func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
-	cfgCache.Store(cfg, frozenConfig)
-}
-
-// Froze forge API from config
-func (cfg Config) Froze() API {
-	api := &frozenConfig{
-		sortMapKeys:                   cfg.SortMapKeys,
-		indentionStep:                 cfg.IndentionStep,
-		objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
-		onlyTaggedField:               cfg.OnlyTaggedField,
-		disallowUnknownFields:         cfg.DisallowUnknownFields,
-		caseSensitive:                 cfg.CaseSensitive,
-	}
-	api.streamPool = &sync.Pool{
-		New: func() interface{} {
-			return NewStream(api, nil, 512)
-		},
-	}
-	api.iteratorPool = &sync.Pool{
-		New: func() interface{} {
-			return NewIterator(api)
-		},
-	}
-	api.initCache()
-	encoderExtension := EncoderExtension{}
-	decoderExtension := DecoderExtension{}
-	if cfg.MarshalFloatWith6Digits {
-		api.marshalFloatWith6Digits(encoderExtension)
-	}
-	if cfg.EscapeHTML {
-		api.escapeHTML(encoderExtension)
-	}
-	if cfg.UseNumber {
-		api.useNumber(decoderExtension)
-	}
-	if cfg.ValidateJsonRawMessage {
-		api.validateJsonRawMessage(encoderExtension)
-	}
-	api.encoderExtension = encoderExtension
-	api.decoderExtension = decoderExtension
-	api.configBeforeFrozen = cfg
-	return api
-}
-
-func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig {
-	api := getFrozenConfigFromCache(cfg)
-	if api != nil {
-		return api
-	}
-	api = cfg.Froze().(*frozenConfig)
-	for _, extension := range extraExtensions {
-		api.RegisterExtension(extension)
-	}
-	addFrozenConfigToCache(cfg, api)
-	return api
-}
-
-func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) {
-	encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
-		rawMessage := *(*json.RawMessage)(ptr)
-		iter := cfg.BorrowIterator([]byte(rawMessage))
-		iter.Read()
-		if iter.Error != nil {
-			stream.WriteRaw("null")
-		} else {
-			cfg.ReturnIterator(iter)
-			stream.WriteRaw(string(rawMessage))
-		}
-	}, func(ptr unsafe.Pointer) bool {
-		return len(*((*json.RawMessage)(ptr))) == 0
-	}}
-	extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder
-	extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder
-}
-
-func (cfg *frozenConfig) useNumber(extension DecoderExtension) {
-	extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
-		exitingValue := *((*interface{})(ptr))
-		if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr {
-			iter.ReadVal(exitingValue)
-			return
-		}
-		if iter.WhatIsNext() == NumberValue {
-			*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
-		} else {
-			*((*interface{})(ptr)) = iter.Read()
-		}
-	}}
-}
-func (cfg *frozenConfig) getTagKey() string {
-	tagKey := cfg.configBeforeFrozen.TagKey
-	if tagKey == "" {
-		return "json"
-	}
-	return tagKey
-}
-
-func (cfg *frozenConfig) RegisterExtension(extension Extension) {
-	cfg.extraExtensions = append(cfg.extraExtensions, extension)
-	copied := cfg.configBeforeFrozen
-	cfg.configBeforeFrozen = copied
-}
-
-type lossyFloat32Encoder struct {
-}
-
-func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteFloat32Lossy(*((*float32)(ptr)))
-}
-
-func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*float32)(ptr)) == 0
-}
-
-type lossyFloat64Encoder struct {
-}
-
-func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteFloat64Lossy(*((*float64)(ptr)))
-}
-
-func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*float64)(ptr)) == 0
-}
-
-// EnableLossyFloatMarshalling keeps 10**(-6) precision
-// for float variables for better performance.
-func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) {
-	// for better performance
-	extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{}
-	extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{}
-}
-
-type htmlEscapedStringEncoder struct {
-}
-
-func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	str := *((*string)(ptr))
-	stream.WriteStringWithHTMLEscaped(str)
-}
-
-func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*string)(ptr)) == ""
-}
-
-func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) {
-	encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{}
-}
-
-func (cfg *frozenConfig) cleanDecoders() {
-	typeDecoders = map[string]ValDecoder{}
-	fieldDecoders = map[string]ValDecoder{}
-	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
-}
-
-func (cfg *frozenConfig) cleanEncoders() {
-	typeEncoders = map[string]ValEncoder{}
-	fieldEncoders = map[string]ValEncoder{}
-	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
-}
-
-func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) {
-	stream := cfg.BorrowStream(nil)
-	defer cfg.ReturnStream(stream)
-	stream.WriteVal(v)
-	if stream.Error != nil {
-		return "", stream.Error
-	}
-	return string(stream.Buffer()), nil
-}
-
-func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
-	stream := cfg.BorrowStream(nil)
-	defer cfg.ReturnStream(stream)
-	stream.WriteVal(v)
-	if stream.Error != nil {
-		return nil, stream.Error
-	}
-	result := stream.Buffer()
-	copied := make([]byte, len(result))
-	copy(copied, result)
-	return copied, nil
-}
-
-func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
-	if prefix != "" {
-		panic("prefix is not supported")
-	}
-	for _, r := range indent {
-		if r != ' ' {
-			panic("indent can only be space")
-		}
-	}
-	newCfg := cfg.configBeforeFrozen
-	newCfg.IndentionStep = len(indent)
-	return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v)
-}
-
-func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
-	data := []byte(str)
-	iter := cfg.BorrowIterator(data)
-	defer cfg.ReturnIterator(iter)
-	iter.ReadVal(v)
-	c := iter.nextToken()
-	if c == 0 {
-		if iter.Error == io.EOF {
-			return nil
-		}
-		return iter.Error
-	}
-	iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
-	return iter.Error
-}
-
-func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any {
-	iter := cfg.BorrowIterator(data)
-	defer cfg.ReturnIterator(iter)
-	return locatePath(iter, path)
-}
-
-func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
-	iter := cfg.BorrowIterator(data)
-	defer cfg.ReturnIterator(iter)
-	iter.ReadVal(v)
-	c := iter.nextToken()
-	if c == 0 {
-		if iter.Error == io.EOF {
-			return nil
-		}
-		return iter.Error
-	}
-	iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
-	return iter.Error
-}
-
-func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder {
-	stream := NewStream(cfg, writer, 512)
-	return &Encoder{stream}
-}
-
-func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder {
-	iter := Parse(cfg, reader, 512)
-	return &Decoder{iter}
-}
-
-func (cfg *frozenConfig) Valid(data []byte) bool {
-	iter := cfg.BorrowIterator(data)
-	defer cfg.ReturnIterator(iter)
-	iter.Skip()
-	return iter.Error == nil
-}
diff --git a/vendor/github.com/json-iterator/go/adapter.go b/vendor/github.com/json-iterator/go/feature_adapter.go
similarity index 70%
rename from vendor/github.com/json-iterator/go/adapter.go
rename to vendor/github.com/json-iterator/go/feature_adapter.go
index e674d0f39..edb477c4f 100644
--- a/vendor/github.com/json-iterator/go/adapter.go
+++ b/vendor/github.com/json-iterator/go/feature_adapter.go
@@ -16,6 +16,15 @@ func Unmarshal(data []byte, v interface{}) error {
 	return ConfigDefault.Unmarshal(data, v)
 }
 
+func lastNotSpacePos(data []byte) int {
+	for i := len(data) - 1; i >= 0; i-- {
+		if data[i] != ' ' && data[i] != '\t' && data[i] != '\r' && data[i] != '\n' {
+			return i + 1
+		}
+	}
+	return 0
+}
+
 // UnmarshalFromString convenient method to read from string instead of []byte
 func UnmarshalFromString(str string, v interface{}) error {
 	return ConfigDefault.UnmarshalFromString(str, v)
@@ -62,11 +71,6 @@ type Decoder struct {
 
 // Decode decode JSON into interface{}
 func (adapter *Decoder) Decode(obj interface{}) error {
-	if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil {
-		if !adapter.iter.loadMore() {
-			return io.EOF
-		}
-	}
 	adapter.iter.ReadVal(obj)
 	err := adapter.iter.Error
 	if err == io.EOF {
@@ -77,16 +81,7 @@ func (adapter *Decoder) Decode(obj interface{}) error {
 
 // More is there more?
 func (adapter *Decoder) More() bool {
-	iter := adapter.iter
-	if iter.Error != nil {
-		return false
-	}
-	c := iter.nextToken()
-	if c == 0 {
-		return false
-	}
-	iter.unreadByte()
-	return c != ']' && c != '}'
+	return adapter.iter.head != adapter.iter.tail
 }
 
 // Buffered remaining buffer
@@ -95,21 +90,11 @@ func (adapter *Decoder) Buffered() io.Reader {
 	return bytes.NewReader(remaining)
 }
 
-// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
-// Number instead of as a float64.
+// UseNumber for number JSON element, use float64 or json.NumberValue (alias of string)
 func (adapter *Decoder) UseNumber() {
-	cfg := adapter.iter.cfg.configBeforeFrozen
-	cfg.UseNumber = true
-	adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions)
-}
-
-// DisallowUnknownFields causes the Decoder to return an error when the destination
-// is a struct and the input contains object keys which do not match any
-// non-ignored, exported fields in the destination.
-func (adapter *Decoder) DisallowUnknownFields() {
-	cfg := adapter.iter.cfg.configBeforeFrozen
-	cfg.DisallowUnknownFields = true
-	adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions)
+	origCfg := adapter.iter.cfg.configBeforeFrozen
+	origCfg.UseNumber = true
+	adapter.iter.cfg = origCfg.Froze().(*frozenConfig)
 }
 
 // NewEncoder same as json.NewEncoder
@@ -125,26 +110,18 @@ type Encoder struct {
 // Encode encode interface{} as JSON to io.Writer
 func (adapter *Encoder) Encode(val interface{}) error {
 	adapter.stream.WriteVal(val)
-	adapter.stream.WriteRaw("\n")
 	adapter.stream.Flush()
 	return adapter.stream.Error
 }
 
 // SetIndent set the indention. Prefix is not supported
 func (adapter *Encoder) SetIndent(prefix, indent string) {
-	config := adapter.stream.cfg.configBeforeFrozen
-	config.IndentionStep = len(indent)
-	adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions)
+	adapter.stream.cfg.indentionStep = len(indent)
 }
 
 // SetEscapeHTML escape html by default, set to false to disable
 func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) {
 	config := adapter.stream.cfg.configBeforeFrozen
 	config.EscapeHTML = escapeHTML
-	adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions)
-}
-
-// Valid reports whether data is a valid JSON encoding.
-func Valid(data []byte) bool {
-	return ConfigDefault.Valid(data)
+	adapter.stream.cfg = config.Froze().(*frozenConfig)
 }
diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/feature_any.go
similarity index 74%
rename from vendor/github.com/json-iterator/go/any.go
rename to vendor/github.com/json-iterator/go/feature_any.go
index daecfed61..6733dce4c 100644
--- a/vendor/github.com/json-iterator/go/any.go
+++ b/vendor/github.com/json-iterator/go/feature_any.go
@@ -1,13 +1,9 @@
 package jsoniter
 
 import (
-	"errors"
 	"fmt"
-	"github.com/modern-go/reflect2"
 	"io"
 	"reflect"
-	"strconv"
-	"unsafe"
 )
 
 // Any generic object representation.
@@ -28,6 +24,7 @@ type Any interface {
 	ToString() string
 	ToVal(val interface{})
 	Get(path ...interface{}) Any
+	// TODO: add Set
 	Size() int
 	Keys() []string
 	GetInterface() interface{}
@@ -37,7 +34,7 @@ type Any interface {
 type baseAny struct{}
 
 func (any *baseAny) Get(path ...interface{}) Any {
-	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
+	return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
 }
 
 func (any *baseAny) Size() int {
@@ -91,7 +88,7 @@ func Wrap(val interface{}) Any {
 	if isAny {
 		return asAny
 	}
-	typ := reflect2.TypeOf(val)
+	typ := reflect.TypeOf(val)
 	switch typ.Kind() {
 	case reflect.Slice:
 		return wrapArray(val)
@@ -102,9 +99,6 @@ func Wrap(val interface{}) Any {
 	case reflect.String:
 		return WrapString(val.(string))
 	case reflect.Int:
-		if strconv.IntSize == 32 {
-			return WrapInt32(int32(val.(int)))
-		}
 		return WrapInt64(int64(val.(int)))
 	case reflect.Int8:
 		return WrapInt32(int32(val.(int8)))
@@ -115,15 +109,7 @@ func Wrap(val interface{}) Any {
 	case reflect.Int64:
 		return WrapInt64(val.(int64))
 	case reflect.Uint:
-		if strconv.IntSize == 32 {
-			return WrapUint32(uint32(val.(uint)))
-		}
 		return WrapUint64(uint64(val.(uint)))
-	case reflect.Uintptr:
-		if ptrSize == 32 {
-			return WrapUint32(uint32(val.(uintptr)))
-		}
-		return WrapUint64(uint64(val.(uintptr)))
 	case reflect.Uint8:
 		return WrapUint32(uint32(val.(uint8)))
 	case reflect.Uint16:
@@ -171,8 +157,6 @@ func (iter *Iterator) readAny() Any {
 		return iter.readArrayAny()
 	case '-':
 		return iter.readNumberAny(false)
-	case 0:
-		return &invalidAny{baseAny{}, errors.New("input is empty")}
 	default:
 		return iter.readNumberAny(true)
 	}
@@ -256,66 +240,3 @@ func locatePath(iter *Iterator, path []interface{}) Any {
 	}
 	return iter.readAny()
 }
-
-var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem()
-
-func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder {
-	if typ == anyType {
-		return &directAnyCodec{}
-	}
-	if typ.Implements(anyType) {
-		return &anyCodec{
-			valType: typ,
-		}
-	}
-	return nil
-}
-
-func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder {
-	if typ == anyType {
-		return &directAnyCodec{}
-	}
-	if typ.Implements(anyType) {
-		return &anyCodec{
-			valType: typ,
-		}
-	}
-	return nil
-}
-
-type anyCodec struct {
-	valType reflect2.Type
-}
-
-func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	panic("not implemented")
-}
-
-func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	obj := codec.valType.UnsafeIndirect(ptr)
-	any := obj.(Any)
-	any.WriteTo(stream)
-}
-
-func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	obj := codec.valType.UnsafeIndirect(ptr)
-	any := obj.(Any)
-	return any.Size() == 0
-}
-
-type directAnyCodec struct {
-}
-
-func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	*(*Any)(ptr) = iter.readAny()
-}
-
-func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	any := *(*Any)(ptr)
-	any.WriteTo(stream)
-}
-
-func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	any := *(*Any)(ptr)
-	return any.Size() == 0
-}
diff --git a/vendor/github.com/json-iterator/go/any_array.go b/vendor/github.com/json-iterator/go/feature_any_array.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_array.go
rename to vendor/github.com/json-iterator/go/feature_any_array.go
diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/feature_any_bool.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_bool.go
rename to vendor/github.com/json-iterator/go/feature_any_bool.go
diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/feature_any_float.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_float.go
rename to vendor/github.com/json-iterator/go/feature_any_float.go
diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/feature_any_int32.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_int32.go
rename to vendor/github.com/json-iterator/go/feature_any_int32.go
diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/feature_any_int64.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_int64.go
rename to vendor/github.com/json-iterator/go/feature_any_int64.go
diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/feature_any_invalid.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_invalid.go
rename to vendor/github.com/json-iterator/go/feature_any_invalid.go
diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/feature_any_nil.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_nil.go
rename to vendor/github.com/json-iterator/go/feature_any_nil.go
diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/feature_any_number.go
similarity index 76%
rename from vendor/github.com/json-iterator/go/any_number.go
rename to vendor/github.com/json-iterator/go/feature_any_number.go
index 9d1e901a6..4e1c27641 100644
--- a/vendor/github.com/json-iterator/go/any_number.go
+++ b/vendor/github.com/json-iterator/go/feature_any_number.go
@@ -1,9 +1,6 @@
 package jsoniter
 
-import (
-	"io"
-	"unsafe"
-)
+import "unsafe"
 
 type numberLazyAny struct {
 	baseAny
@@ -32,9 +29,7 @@ func (any *numberLazyAny) ToInt() int {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadInt()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
@@ -42,9 +37,7 @@ func (any *numberLazyAny) ToInt32() int32 {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadInt32()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
@@ -52,9 +45,7 @@ func (any *numberLazyAny) ToInt64() int64 {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadInt64()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
@@ -62,9 +53,7 @@ func (any *numberLazyAny) ToUint() uint {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadUint()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
@@ -72,9 +61,7 @@ func (any *numberLazyAny) ToUint32() uint32 {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadUint32()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
@@ -82,9 +69,7 @@ func (any *numberLazyAny) ToUint64() uint64 {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadUint64()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
@@ -92,9 +77,7 @@ func (any *numberLazyAny) ToFloat32() float32 {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadFloat32()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
@@ -102,9 +85,7 @@ func (any *numberLazyAny) ToFloat64() float64 {
 	iter := any.cfg.BorrowIterator(any.buf)
 	defer any.cfg.ReturnIterator(iter)
 	val := iter.ReadFloat64()
-	if iter.Error != nil && iter.Error != io.EOF {
-		any.err = iter.Error
-	}
+	any.err = iter.Error
 	return val
 }
 
diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/feature_any_object.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_object.go
rename to vendor/github.com/json-iterator/go/feature_any_object.go
diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/feature_any_string.go
similarity index 97%
rename from vendor/github.com/json-iterator/go/any_str.go
rename to vendor/github.com/json-iterator/go/feature_any_string.go
index a4b93c78c..abf060bd5 100644
--- a/vendor/github.com/json-iterator/go/any_str.go
+++ b/vendor/github.com/json-iterator/go/feature_any_string.go
@@ -14,7 +14,7 @@ func (any *stringAny) Get(path ...interface{}) Any {
 	if len(path) == 0 {
 		return any
 	}
-	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
+	return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
 }
 
 func (any *stringAny) Parse() *Iterator {
diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/feature_any_uint32.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_uint32.go
rename to vendor/github.com/json-iterator/go/feature_any_uint32.go
diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/feature_any_uint64.go
similarity index 100%
rename from vendor/github.com/json-iterator/go/any_uint64.go
rename to vendor/github.com/json-iterator/go/feature_any_uint64.go
diff --git a/vendor/github.com/json-iterator/go/feature_config.go b/vendor/github.com/json-iterator/go/feature_config.go
new file mode 100644
index 000000000..fc055d504
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_config.go
@@ -0,0 +1,312 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"errors"
+	"io"
+	"reflect"
+	"sync/atomic"
+	"unsafe"
+)
+
+// Config customize how the API should behave.
+// The API is created from Config by Froze.
+type Config struct {
+	IndentionStep           int
+	MarshalFloatWith6Digits bool
+	EscapeHTML              bool
+	SortMapKeys             bool
+	UseNumber               bool
+	TagKey                  string
+}
+
+type frozenConfig struct {
+	configBeforeFrozen Config
+	sortMapKeys        bool
+	indentionStep      int
+	decoderCache       unsafe.Pointer
+	encoderCache       unsafe.Pointer
+	extensions         []Extension
+	streamPool         chan *Stream
+	iteratorPool       chan *Iterator
+}
+
+// API the public interface of this package.
+// Primary Marshal and Unmarshal.
+type API interface {
+	IteratorPool
+	StreamPool
+	MarshalToString(v interface{}) (string, error)
+	Marshal(v interface{}) ([]byte, error)
+	MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
+	UnmarshalFromString(str string, v interface{}) error
+	Unmarshal(data []byte, v interface{}) error
+	Get(data []byte, path ...interface{}) Any
+	NewEncoder(writer io.Writer) *Encoder
+	NewDecoder(reader io.Reader) *Decoder
+}
+
+// ConfigDefault the default API
+var ConfigDefault = Config{
+	EscapeHTML: true,
+}.Froze()
+
+// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
+var ConfigCompatibleWithStandardLibrary = Config{
+	EscapeHTML:  true,
+	SortMapKeys: true,
+}.Froze()
+
+// ConfigFastest marshals float with only 6 digits precision
+var ConfigFastest = Config{
+	EscapeHTML:              false,
+	MarshalFloatWith6Digits: true,
+}.Froze()
+
+// Froze forge API from config
+func (cfg Config) Froze() API {
+	// TODO: cache frozen config
+	frozenConfig := &frozenConfig{
+		sortMapKeys:   cfg.SortMapKeys,
+		indentionStep: cfg.IndentionStep,
+		streamPool:    make(chan *Stream, 16),
+		iteratorPool:  make(chan *Iterator, 16),
+	}
+	atomic.StorePointer(&frozenConfig.decoderCache, unsafe.Pointer(&map[string]ValDecoder{}))
+	atomic.StorePointer(&frozenConfig.encoderCache, unsafe.Pointer(&map[string]ValEncoder{}))
+	if cfg.MarshalFloatWith6Digits {
+		frozenConfig.marshalFloatWith6Digits()
+	}
+	if cfg.EscapeHTML {
+		frozenConfig.escapeHTML()
+	}
+	if cfg.UseNumber {
+		frozenConfig.useNumber()
+	}
+	frozenConfig.configBeforeFrozen = cfg
+	return frozenConfig
+}
+
+func (cfg *frozenConfig) useNumber() {
+	cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
+		if iter.WhatIsNext() == NumberValue {
+			*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
+		} else {
+			*((*interface{})(ptr)) = iter.Read()
+		}
+	}})
+}
+func (cfg *frozenConfig) getTagKey() string {
+	tagKey := cfg.configBeforeFrozen.TagKey
+	if tagKey == "" {
+		return "json"
+	}
+	return tagKey
+}
+
+func (cfg *frozenConfig) registerExtension(extension Extension) {
+	cfg.extensions = append(cfg.extensions, extension)
+}
+
+type lossyFloat32Encoder struct {
+}
+
+func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat32Lossy(*((*float32)(ptr)))
+}
+
+func (encoder *lossyFloat32Encoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float32)(ptr)) == 0
+}
+
+type lossyFloat64Encoder struct {
+}
+
+func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat64Lossy(*((*float64)(ptr)))
+}
+
+func (encoder *lossyFloat64Encoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float64)(ptr)) == 0
+}
+
+// EnableLossyFloatMarshalling keeps 10**(-6) precision
+// for float variables for better performance.
+func (cfg *frozenConfig) marshalFloatWith6Digits() {
+	// for better performance
+	cfg.addEncoderToCache(reflect.TypeOf((*float32)(nil)).Elem(), &lossyFloat32Encoder{})
+	cfg.addEncoderToCache(reflect.TypeOf((*float64)(nil)).Elem(), &lossyFloat64Encoder{})
+}
+
+type htmlEscapedStringEncoder struct {
+}
+
+func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	str := *((*string)(ptr))
+	stream.WriteStringWithHTMLEscaped(str)
+}
+
+func (encoder *htmlEscapedStringEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*string)(ptr)) == ""
+}
+
+func (cfg *frozenConfig) escapeHTML() {
+	cfg.addEncoderToCache(reflect.TypeOf((*string)(nil)).Elem(), &htmlEscapedStringEncoder{})
+}
+
+func (cfg *frozenConfig) addDecoderToCache(cacheKey reflect.Type, decoder ValDecoder) {
+	done := false
+	for !done {
+		ptr := atomic.LoadPointer(&cfg.decoderCache)
+		cache := *(*map[reflect.Type]ValDecoder)(ptr)
+		copied := map[reflect.Type]ValDecoder{}
+		for k, v := range cache {
+			copied[k] = v
+		}
+		copied[cacheKey] = decoder
+		done = atomic.CompareAndSwapPointer(&cfg.decoderCache, ptr, unsafe.Pointer(&copied))
+	}
+}
+
+func (cfg *frozenConfig) addEncoderToCache(cacheKey reflect.Type, encoder ValEncoder) {
+	done := false
+	for !done {
+		ptr := atomic.LoadPointer(&cfg.encoderCache)
+		cache := *(*map[reflect.Type]ValEncoder)(ptr)
+		copied := map[reflect.Type]ValEncoder{}
+		for k, v := range cache {
+			copied[k] = v
+		}
+		copied[cacheKey] = encoder
+		done = atomic.CompareAndSwapPointer(&cfg.encoderCache, ptr, unsafe.Pointer(&copied))
+	}
+}
+
+func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect.Type) ValDecoder {
+	ptr := atomic.LoadPointer(&cfg.decoderCache)
+	cache := *(*map[reflect.Type]ValDecoder)(ptr)
+	return cache[cacheKey]
+}
+
+func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder {
+	ptr := atomic.LoadPointer(&cfg.encoderCache)
+	cache := *(*map[reflect.Type]ValEncoder)(ptr)
+	return cache[cacheKey]
+}
+
+func (cfg *frozenConfig) cleanDecoders() {
+	typeDecoders = map[string]ValDecoder{}
+	fieldDecoders = map[string]ValDecoder{}
+	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
+}
+
+func (cfg *frozenConfig) cleanEncoders() {
+	typeEncoders = map[string]ValEncoder{}
+	fieldEncoders = map[string]ValEncoder{}
+	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
+}
+
+func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) {
+	stream := cfg.BorrowStream(nil)
+	defer cfg.ReturnStream(stream)
+	stream.WriteVal(v)
+	if stream.Error != nil {
+		return "", stream.Error
+	}
+	return string(stream.Buffer()), nil
+}
+
+func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
+	stream := cfg.BorrowStream(nil)
+	defer cfg.ReturnStream(stream)
+	stream.WriteVal(v)
+	if stream.Error != nil {
+		return nil, stream.Error
+	}
+	result := stream.Buffer()
+	copied := make([]byte, len(result))
+	copy(copied, result)
+	return copied, nil
+}
+
+func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
+	if prefix != "" {
+		panic("prefix is not supported")
+	}
+	for _, r := range indent {
+		if r != ' ' {
+			panic("indent can only be space")
+		}
+	}
+	newCfg := cfg.configBeforeFrozen
+	newCfg.IndentionStep = len(indent)
+	return newCfg.Froze().Marshal(v)
+}
+
+func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
+	data := []byte(str)
+	data = data[:lastNotSpacePos(data)]
+	iter := cfg.BorrowIterator(data)
+	defer cfg.ReturnIterator(iter)
+	iter.ReadVal(v)
+	if iter.head == iter.tail {
+		iter.loadMore()
+	}
+	if iter.Error == io.EOF {
+		return nil
+	}
+	if iter.Error == nil {
+		iter.ReportError("UnmarshalFromString", "there are bytes left after unmarshal")
+	}
+	return iter.Error
+}
+
+func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any {
+	iter := cfg.BorrowIterator(data)
+	defer cfg.ReturnIterator(iter)
+	return locatePath(iter, path)
+}
+
+func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
+	data = data[:lastNotSpacePos(data)]
+	iter := cfg.BorrowIterator(data)
+	defer cfg.ReturnIterator(iter)
+	typ := reflect.TypeOf(v)
+	if typ.Kind() != reflect.Ptr {
+		// return non-pointer error
+		return errors.New("the second param must be ptr type")
+	}
+	iter.ReadVal(v)
+	if iter.head == iter.tail {
+		iter.loadMore()
+	}
+	if iter.Error == io.EOF {
+		return nil
+	}
+	if iter.Error == nil {
+		iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
+	}
+	return iter.Error
+}
+
+func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder {
+	stream := NewStream(cfg, writer, 512)
+	return &Encoder{stream}
+}
+
+func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder {
+	iter := Parse(cfg, reader, 512)
+	return &Decoder{iter}
+}
diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/feature_iter.go
similarity index 89%
rename from vendor/github.com/json-iterator/go/iter.go
rename to vendor/github.com/json-iterator/go/feature_iter.go
index 95ae54fbf..4357d69ba 100644
--- a/vendor/github.com/json-iterator/go/iter.go
+++ b/vendor/github.com/json-iterator/go/feature_iter.go
@@ -77,7 +77,6 @@ type Iterator struct {
 	captureStartedAt int
 	captured         []byte
 	Error            error
-	Attachment       interface{} // open for customized decoder
 }
 
 // NewIterator creates an empty Iterator instance
@@ -168,7 +167,7 @@ func (iter *Iterator) isObjectEnd() bool {
 	if c == '}' {
 		return true
 	}
-	iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
+	iter.ReportError("isObjectEnd", "object ended prematurely")
 	return true
 }
 
@@ -201,22 +200,8 @@ func (iter *Iterator) ReportError(operation string, msg string) {
 	if peekStart < 0 {
 		peekStart = 0
 	}
-	peekEnd := iter.head + 10
-	if peekEnd > iter.tail {
-		peekEnd = iter.tail
-	}
-	parsing := string(iter.buf[peekStart:peekEnd])
-	contextStart := iter.head - 50
-	if contextStart < 0 {
-		contextStart = 0
-	}
-	contextEnd := iter.head + 50
-	if contextEnd > iter.tail {
-		contextEnd = iter.tail
-	}
-	context := string(iter.buf[contextStart:contextEnd])
-	iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
-		operation, msg, iter.head-peekStart, parsing, context)
+	iter.Error = fmt.Errorf("%s: %s, parsing %v ...%s... at %s", operation, msg, iter.head,
+		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
 }
 
 // CurrentBuffer gets current buffer as string for debugging purpose
@@ -225,7 +210,7 @@ func (iter *Iterator) CurrentBuffer() string {
 	if peekStart < 0 {
 		peekStart = 0
 	}
-	return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
+	return fmt.Sprintf("parsing %v ...|%s|... at %s", iter.head,
 		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
 }
 
diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/feature_iter_array.go
similarity index 84%
rename from vendor/github.com/json-iterator/go/iter_array.go
rename to vendor/github.com/json-iterator/go/feature_iter_array.go
index 6188cb457..cbc3ec8d1 100644
--- a/vendor/github.com/json-iterator/go/iter_array.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_array.go
@@ -19,7 +19,7 @@ func (iter *Iterator) ReadArray() (ret bool) {
 	case ',':
 		return true
 	default:
-		iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c}))
+		iter.ReportError("ReadArray", "expect [ or , or ] or n, but found: "+string([]byte{c}))
 		return
 	}
 }
@@ -42,7 +42,7 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
 				c = iter.nextToken()
 			}
 			if c != ']' {
-				iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c}))
+				iter.ReportError("ReadArrayCB", "expect ] in the end")
 				return false
 			}
 			return true
@@ -53,6 +53,6 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
 		iter.skipThreeBytes('u', 'l', 'l')
 		return true // null
 	}
-	iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c}))
+	iter.ReportError("ReadArrayCB", "expect [ or n, but found: "+string([]byte{c}))
 	return false
 }
diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/feature_iter_float.go
similarity index 98%
rename from vendor/github.com/json-iterator/go/iter_float.go
rename to vendor/github.com/json-iterator/go/feature_iter_float.go
index 4f883c095..86f459912 100644
--- a/vendor/github.com/json-iterator/go/iter_float.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_float.go
@@ -1,7 +1,6 @@
 package jsoniter
 
 import (
-	"encoding/json"
 	"io"
 	"math/big"
 	"strconv"
@@ -340,8 +339,3 @@ func validateFloat(str string) string {
 	}
 	return ""
 }
-
-// ReadNumber read json.Number
-func (iter *Iterator) ReadNumber() (ret json.Number) {
-	return json.Number(iter.readNumberAsString())
-}
diff --git a/vendor/github.com/json-iterator/go/iter_int.go b/vendor/github.com/json-iterator/go/feature_iter_int.go
similarity index 72%
rename from vendor/github.com/json-iterator/go/iter_int.go
rename to vendor/github.com/json-iterator/go/feature_iter_int.go
index 214232035..886879efd 100644
--- a/vendor/github.com/json-iterator/go/iter_int.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_int.go
@@ -22,17 +22,11 @@ func init() {
 
 // ReadUint read uint
 func (iter *Iterator) ReadUint() uint {
-	if strconv.IntSize == 32 {
-		return uint(iter.ReadUint32())
-	}
 	return uint(iter.ReadUint64())
 }
 
 // ReadInt read int
 func (iter *Iterator) ReadInt() int {
-	if strconv.IntSize == 32 {
-		return int(iter.ReadInt32())
-	}
 	return int(iter.ReadInt64())
 }
 
@@ -121,7 +115,6 @@ func (iter *Iterator) ReadUint32() (ret uint32) {
 func (iter *Iterator) readUint32(c byte) (ret uint32) {
 	ind := intDigits[c]
 	if ind == 0 {
-		iter.assertInteger()
 		return 0 // single zero
 	}
 	if ind == invalidCharForNumber {
@@ -134,14 +127,12 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
 		ind2 := intDigits[iter.buf[i]]
 		if ind2 == invalidCharForNumber {
 			iter.head = i
-			iter.assertInteger()
 			return value
 		}
 		i++
 		ind3 := intDigits[iter.buf[i]]
 		if ind3 == invalidCharForNumber {
 			iter.head = i
-			iter.assertInteger()
 			return value*10 + uint32(ind2)
 		}
 		//iter.head = i + 1
@@ -150,35 +141,30 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
 		ind4 := intDigits[iter.buf[i]]
 		if ind4 == invalidCharForNumber {
 			iter.head = i
-			iter.assertInteger()
 			return value*100 + uint32(ind2)*10 + uint32(ind3)
 		}
 		i++
 		ind5 := intDigits[iter.buf[i]]
 		if ind5 == invalidCharForNumber {
 			iter.head = i
-			iter.assertInteger()
 			return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4)
 		}
 		i++
 		ind6 := intDigits[iter.buf[i]]
 		if ind6 == invalidCharForNumber {
 			iter.head = i
-			iter.assertInteger()
 			return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5)
 		}
 		i++
 		ind7 := intDigits[iter.buf[i]]
 		if ind7 == invalidCharForNumber {
 			iter.head = i
-			iter.assertInteger()
 			return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6)
 		}
 		i++
 		ind8 := intDigits[iter.buf[i]]
 		if ind8 == invalidCharForNumber {
 			iter.head = i
-			iter.assertInteger()
 			return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7)
 		}
 		i++
@@ -186,7 +172,6 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
 		value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8)
 		iter.head = i
 		if ind9 == invalidCharForNumber {
-			iter.assertInteger()
 			return value
 		}
 	}
@@ -195,7 +180,6 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
 			ind = intDigits[iter.buf[i]]
 			if ind == invalidCharForNumber {
 				iter.head = i
-				iter.assertInteger()
 				return value
 			}
 			if value > uint32SafeToMultiply10 {
@@ -210,7 +194,6 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
 			value = (value << 3) + (value << 1) + uint32(ind)
 		}
 		if !iter.loadMore() {
-			iter.assertInteger()
 			return value
 		}
 	}
@@ -243,7 +226,6 @@ func (iter *Iterator) ReadUint64() uint64 {
 func (iter *Iterator) readUint64(c byte) (ret uint64) {
 	ind := intDigits[c]
 	if ind == 0 {
-		iter.assertInteger()
 		return 0 // single zero
 	}
 	if ind == invalidCharForNumber {
@@ -251,73 +233,11 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) {
 		return
 	}
 	value := uint64(ind)
-	if iter.tail-iter.head > 10 {
-		i := iter.head
-		ind2 := intDigits[iter.buf[i]]
-		if ind2 == invalidCharForNumber {
-			iter.head = i
-			iter.assertInteger()
-			return value
-		}
-		i++
-		ind3 := intDigits[iter.buf[i]]
-		if ind3 == invalidCharForNumber {
-			iter.head = i
-			iter.assertInteger()
-			return value*10 + uint64(ind2)
-		}
-		//iter.head = i + 1
-		//value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
-		i++
-		ind4 := intDigits[iter.buf[i]]
-		if ind4 == invalidCharForNumber {
-			iter.head = i
-			iter.assertInteger()
-			return value*100 + uint64(ind2)*10 + uint64(ind3)
-		}
-		i++
-		ind5 := intDigits[iter.buf[i]]
-		if ind5 == invalidCharForNumber {
-			iter.head = i
-			iter.assertInteger()
-			return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4)
-		}
-		i++
-		ind6 := intDigits[iter.buf[i]]
-		if ind6 == invalidCharForNumber {
-			iter.head = i
-			iter.assertInteger()
-			return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5)
-		}
-		i++
-		ind7 := intDigits[iter.buf[i]]
-		if ind7 == invalidCharForNumber {
-			iter.head = i
-			iter.assertInteger()
-			return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6)
-		}
-		i++
-		ind8 := intDigits[iter.buf[i]]
-		if ind8 == invalidCharForNumber {
-			iter.head = i
-			iter.assertInteger()
-			return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7)
-		}
-		i++
-		ind9 := intDigits[iter.buf[i]]
-		value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8)
-		iter.head = i
-		if ind9 == invalidCharForNumber {
-			iter.assertInteger()
-			return value
-		}
-	}
 	for {
 		for i := iter.head; i < iter.tail; i++ {
 			ind = intDigits[iter.buf[i]]
 			if ind == invalidCharForNumber {
 				iter.head = i
-				iter.assertInteger()
 				return value
 			}
 			if value > uint64SafeToMultiple10 {
@@ -332,14 +252,7 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) {
 			value = (value << 3) + (value << 1) + uint64(ind)
 		}
 		if !iter.loadMore() {
-			iter.assertInteger()
 			return value
 		}
 	}
 }
-
-func (iter *Iterator) assertInteger() {
-	if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' {
-		iter.ReportError("assertInteger", "can not decode float as int")
-	}
-}
diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/feature_iter_object.go
similarity index 53%
rename from vendor/github.com/json-iterator/go/iter_object.go
rename to vendor/github.com/json-iterator/go/feature_iter_object.go
index 1c5757671..3bdb5576e 100644
--- a/vendor/github.com/json-iterator/go/iter_object.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_object.go
@@ -2,7 +2,8 @@ package jsoniter
 
 import (
 	"fmt"
-	"strings"
+	"unicode"
+	"unsafe"
 )
 
 // ReadObject read one field from object.
@@ -18,25 +19,15 @@ func (iter *Iterator) ReadObject() (ret string) {
 		c = iter.nextToken()
 		if c == '"' {
 			iter.unreadByte()
-			field := iter.ReadString()
-			c = iter.nextToken()
-			if c != ':' {
-				iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
-			}
-			return field
+			return string(iter.readObjectFieldAsBytes())
 		}
 		if c == '}' {
 			return "" // end of object
 		}
-		iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c}))
+		iter.ReportError("ReadObject", `expect " after {`)
 		return
 	case ',':
-		field := iter.ReadString()
-		c = iter.nextToken()
-		if c != ':' {
-			iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
-		}
-		return field
+		return string(iter.readObjectFieldAsBytes())
 	case '}':
 		return "" // end of object
 	default:
@@ -45,92 +36,62 @@ func (iter *Iterator) ReadObject() (ret string) {
 	}
 }
 
-// CaseInsensitive
-func (iter *Iterator) readFieldHash() int64 {
+func (iter *Iterator) readFieldHash() int32 {
 	hash := int64(0x811c9dc5)
 	c := iter.nextToken()
-	if c != '"' {
-		iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
-		return 0
-	}
-	for {
-		for i := iter.head; i < iter.tail; i++ {
-			// require ascii string and no escape
-			b := iter.buf[i]
-			if b == '\\' {
-				iter.head = i
-				for _, b := range iter.readStringSlowPath() {
-					if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
-						b += 'a' - 'A'
-					}
-					hash ^= int64(b)
-					hash *= 0x1000193
-				}
-				c = iter.nextToken()
-				if c != ':' {
-					iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
-					return 0
+	if c == '"' {
+		for {
+			for i := iter.head; i < iter.tail; i++ {
+				// require ascii string and no escape
+				b := iter.buf[i]
+				if 'A' <= b && b <= 'Z' {
+					b += 'a' - 'A'
 				}
-				return hash
-			}
-			if b == '"' {
-				iter.head = i + 1
-				c = iter.nextToken()
-				if c != ':' {
-					iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
-					return 0
+				if b == '"' {
+					iter.head = i + 1
+					c = iter.nextToken()
+					if c != ':' {
+						iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
+					}
+					return int32(hash)
 				}
-				return hash
+				hash ^= int64(b)
+				hash *= 0x1000193
 			}
-			if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
-				b += 'a' - 'A'
+			if !iter.loadMore() {
+				iter.ReportError("readFieldHash", `incomplete field name`)
+				return 0
 			}
-			hash ^= int64(b)
-			hash *= 0x1000193
-		}
-		if !iter.loadMore() {
-			iter.ReportError("readFieldHash", `incomplete field name`)
-			return 0
 		}
 	}
+	iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
+	return 0
 }
 
-func calcHash(str string, caseSensitive bool) int64 {
-	if !caseSensitive {
-		str = strings.ToLower(str)
-	}
+func calcHash(str string) int32 {
 	hash := int64(0x811c9dc5)
-	for _, b := range []byte(str) {
-		hash ^= int64(b)
+	for _, b := range str {
+		hash ^= int64(unicode.ToLower(b))
 		hash *= 0x1000193
 	}
-	return int64(hash)
+	return int32(hash)
 }
 
 // ReadObjectCB read object with callback, the key is ascii only and field name not copied
 func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
 	c := iter.nextToken()
-	var field string
 	if c == '{' {
 		c = iter.nextToken()
 		if c == '"' {
 			iter.unreadByte()
-			field = iter.ReadString()
-			c = iter.nextToken()
-			if c != ':' {
-				iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
-			}
-			if !callback(iter, field) {
+			field := iter.readObjectFieldAsBytes()
+			if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
 				return false
 			}
 			c = iter.nextToken()
 			for c == ',' {
-				field = iter.ReadString()
-				c = iter.nextToken()
-				if c != ':' {
-					iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
-				}
-				if !callback(iter, field) {
+				field = iter.readObjectFieldAsBytes()
+				if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
 					return false
 				}
 				c = iter.nextToken()
@@ -144,14 +105,14 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
 		if c == '}' {
 			return true
 		}
-		iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c}))
+		iter.ReportError("ReadObjectCB", `expect " after }`)
 		return false
 	}
 	if c == 'n' {
 		iter.skipThreeBytes('u', 'l', 'l')
 		return true // null
 	}
-	iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c}))
+	iter.ReportError("ReadObjectCB", `expect { or n`)
 	return false
 }
 
@@ -164,7 +125,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
 			iter.unreadByte()
 			field := iter.ReadString()
 			if iter.nextToken() != ':' {
-				iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+				iter.ReportError("ReadMapCB", "expect : after object field")
 				return false
 			}
 			if !callback(iter, field) {
@@ -174,7 +135,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
 			for c == ',' {
 				field = iter.ReadString()
 				if iter.nextToken() != ':' {
-					iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+					iter.ReportError("ReadMapCB", "expect : after object field")
 					return false
 				}
 				if !callback(iter, field) {
@@ -191,14 +152,14 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
 		if c == '}' {
 			return true
 		}
-		iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
+		iter.ReportError("ReadMapCB", `expect " after }`)
 		return false
 	}
 	if c == 'n' {
 		iter.skipThreeBytes('u', 'l', 'l')
 		return true // null
 	}
-	iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
+	iter.ReportError("ReadMapCB", `expect { or n`)
 	return false
 }
 
@@ -215,7 +176,7 @@ func (iter *Iterator) readObjectStart() bool {
 		iter.skipThreeBytes('u', 'l', 'l')
 		return false
 	}
-	iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c}))
+	iter.ReportError("readObjectStart", "expect { or n")
 	return false
 }
 
@@ -231,7 +192,7 @@ func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) {
 		}
 	}
 	if iter.buf[iter.head] != ':' {
-		iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]}))
+		iter.ReportError("readObjectFieldAsBytes", "expect : after object field")
 		return
 	}
 	iter.head++
diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/feature_iter_skip.go
similarity index 95%
rename from vendor/github.com/json-iterator/go/iter_skip.go
rename to vendor/github.com/json-iterator/go/feature_iter_skip.go
index f58beb913..b008d98c9 100644
--- a/vendor/github.com/json-iterator/go/iter_skip.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_skip.go
@@ -25,7 +25,7 @@ func (iter *Iterator) ReadBool() (ret bool) {
 		iter.skipFourBytes('a', 'l', 's', 'e')
 		return false
 	}
-	iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
+	iter.ReportError("ReadBool", "expect t or f")
 	return
 }
 
@@ -59,9 +59,7 @@ func (iter *Iterator) stopCapture() []byte {
 	iter.captureStartedAt = -1
 	iter.captured = nil
 	if len(captured) == 0 {
-		copied := make([]byte, len(remaining))
-		copy(copied, remaining)
-		return copied
+		return remaining
 	}
 	captured = append(captured, remaining...)
 	return captured
diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go
similarity index 99%
rename from vendor/github.com/json-iterator/go/iter_skip_sloppy.go
rename to vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go
index 8fcdc3b69..047d58a4b 100644
--- a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go
@@ -1,4 +1,4 @@
-//+build jsoniter_sloppy
+//+build jsoniter-sloppy
 
 package jsoniter
 
diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go
similarity index 96%
rename from vendor/github.com/json-iterator/go/iter_skip_strict.go
rename to vendor/github.com/json-iterator/go/feature_iter_skip_strict.go
index f67bc2e83..d26763825 100644
--- a/vendor/github.com/json-iterator/go/iter_skip_strict.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go
@@ -1,4 +1,4 @@
-//+build !jsoniter_sloppy
+//+build !jsoniter-sloppy
 
 package jsoniter
 
@@ -64,7 +64,7 @@ func (iter *Iterator) trySkipString() bool {
 		} else if c == '\\' {
 			return false
 		} else if c < ' ' {
-			iter.ReportError("trySkipString",
+			iter.ReportError("ReadString",
 				fmt.Sprintf(`invalid control character found: %d`, c))
 			return true // already failed
 		}
diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/feature_iter_string.go
similarity index 92%
rename from vendor/github.com/json-iterator/go/iter_str.go
rename to vendor/github.com/json-iterator/go/feature_iter_string.go
index adc487ea8..b76460046 100644
--- a/vendor/github.com/json-iterator/go/iter_str.go
+++ b/vendor/github.com/json-iterator/go/feature_iter_string.go
@@ -28,7 +28,7 @@ func (iter *Iterator) ReadString() (ret string) {
 		iter.skipThreeBytes('u', 'l', 'l')
 		return ""
 	}
-	iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c}))
+	iter.ReportError("ReadString", `expects " or n`)
 	return
 }
 
@@ -47,7 +47,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) {
 			str = append(str, c)
 		}
 	}
-	iter.ReportError("readStringSlowPath", "unexpected end of input")
+	iter.ReportError("ReadString", "unexpected end of input")
 	return
 }
 
@@ -104,7 +104,7 @@ func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte {
 	case 't':
 		str = append(str, '\t')
 	default:
-		iter.ReportError("readEscapedChar",
+		iter.ReportError("ReadString",
 			`invalid escape char after \`)
 		return nil
 	}
@@ -139,7 +139,7 @@ func (iter *Iterator) ReadStringAsSlice() (ret []byte) {
 		}
 		return copied
 	}
-	iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c}))
+	iter.ReportError("ReadString", `expects " or n`)
 	return
 }
 
@@ -156,7 +156,7 @@ func (iter *Iterator) readU4() (ret rune) {
 		} else if c >= 'A' && c <= 'F' {
 			ret = ret*16 + rune(c-'A'+10)
 		} else {
-			iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c}))
+			iter.ReportError("readU4", "expects 0~9 or a~f")
 			return
 		}
 	}
diff --git a/vendor/github.com/json-iterator/go/feature_json_number.go b/vendor/github.com/json-iterator/go/feature_json_number.go
new file mode 100644
index 000000000..0439f6725
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_json_number.go
@@ -0,0 +1,15 @@
+package jsoniter
+
+import "encoding/json"
+
+type Number string
+
+func CastJsonNumber(val interface{}) (string, bool) {
+	switch typedVal := val.(type) {
+	case json.Number:
+		return string(typedVal), true
+	case Number:
+		return string(typedVal), true
+	}
+	return "", false
+}
diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/feature_pool.go
similarity index 62%
rename from vendor/github.com/json-iterator/go/pool.go
rename to vendor/github.com/json-iterator/go/feature_pool.go
index e2389b56c..73962bc6f 100644
--- a/vendor/github.com/json-iterator/go/pool.go
+++ b/vendor/github.com/json-iterator/go/feature_pool.go
@@ -17,26 +17,41 @@ type StreamPool interface {
 }
 
 func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream {
-	stream := cfg.streamPool.Get().(*Stream)
-	stream.Reset(writer)
-	return stream
+	select {
+	case stream := <-cfg.streamPool:
+		stream.Reset(writer)
+		return stream
+	default:
+		return NewStream(cfg, writer, 512)
+	}
 }
 
 func (cfg *frozenConfig) ReturnStream(stream *Stream) {
-	stream.out = nil
 	stream.Error = nil
-	stream.Attachment = nil
-	cfg.streamPool.Put(stream)
+	select {
+	case cfg.streamPool <- stream:
+		return
+	default:
+		return
+	}
 }
 
 func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator {
-	iter := cfg.iteratorPool.Get().(*Iterator)
-	iter.ResetBytes(data)
-	return iter
+	select {
+	case iter := <-cfg.iteratorPool:
+		iter.ResetBytes(data)
+		return iter
+	default:
+		return ParseBytes(cfg, data)
+	}
 }
 
 func (cfg *frozenConfig) ReturnIterator(iter *Iterator) {
 	iter.Error = nil
-	iter.Attachment = nil
-	cfg.iteratorPool.Put(iter)
+	select {
+	case cfg.iteratorPool <- iter:
+		return
+	default:
+		return
+	}
 }
diff --git a/vendor/github.com/json-iterator/go/feature_reflect.go b/vendor/github.com/json-iterator/go/feature_reflect.go
new file mode 100644
index 000000000..05d91b49c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_reflect.go
@@ -0,0 +1,691 @@
+package jsoniter
+
+import (
+	"encoding"
+	"encoding/json"
+	"fmt"
+	"reflect"
+	"time"
+	"unsafe"
+)
+
+// ValDecoder is an internal type registered to cache as needed.
+// Don't confuse jsoniter.ValDecoder with json.Decoder.
+// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link).
+//
+// Reflection on type to create decoders, which is then cached
+// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions
+// 1. create instance of new value, for example *int will need a int to be allocated
+// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New
+// 3. assignment to map, both key and value will be reflect.Value
+// For a simple struct binding, it will be reflect.Value free and allocation free
+type ValDecoder interface {
+	Decode(ptr unsafe.Pointer, iter *Iterator)
+}
+
+// ValEncoder is an internal type registered to cache as needed.
+// Don't confuse jsoniter.ValEncoder with json.Encoder.
+// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link).
+type ValEncoder interface {
+	IsEmpty(ptr unsafe.Pointer) bool
+	Encode(ptr unsafe.Pointer, stream *Stream)
+	EncodeInterface(val interface{}, stream *Stream)
+}
+
+type checkIsEmpty interface {
+	IsEmpty(ptr unsafe.Pointer) bool
+}
+
+// WriteToStream the default implementation for TypeEncoder method EncodeInterface
+func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
+	e := (*emptyInterface)(unsafe.Pointer(&val))
+	if e.word == nil {
+		stream.WriteNil()
+		return
+	}
+	if reflect.TypeOf(val).Kind() == reflect.Ptr {
+		encoder.Encode(unsafe.Pointer(&e.word), stream)
+	} else {
+		encoder.Encode(e.word, stream)
+	}
+}
+
+var jsonNumberType reflect.Type
+var jsoniterNumberType reflect.Type
+var jsonRawMessageType reflect.Type
+var jsoniterRawMessageType reflect.Type
+var anyType reflect.Type
+var marshalerType reflect.Type
+var unmarshalerType reflect.Type
+var textMarshalerType reflect.Type
+var textUnmarshalerType reflect.Type
+
+func init() {
+	jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
+	jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem()
+	jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
+	jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
+	anyType = reflect.TypeOf((*Any)(nil)).Elem()
+	marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
+	unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
+	textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+	textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+}
+
+type optionalDecoder struct {
+	valueType    reflect.Type
+	valueDecoder ValDecoder
+}
+
+func (decoder *optionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if iter.ReadNil() {
+		*((*unsafe.Pointer)(ptr)) = nil
+	} else {
+		if *((*unsafe.Pointer)(ptr)) == nil {
+			//pointer to null, we have to allocate memory to hold the value
+			value := reflect.New(decoder.valueType)
+			newPtr := extractInterface(value.Interface()).word
+			decoder.valueDecoder.Decode(newPtr, iter)
+			*((*uintptr)(ptr)) = uintptr(newPtr)
+		} else {
+			//reuse existing instance
+			decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
+		}
+	}
+}
+
+type deferenceDecoder struct {
+	// only to deference a pointer
+	valueType    reflect.Type
+	valueDecoder ValDecoder
+}
+
+func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if *((*unsafe.Pointer)(ptr)) == nil {
+		//pointer to null, we have to allocate memory to hold the value
+		value := reflect.New(decoder.valueType)
+		newPtr := extractInterface(value.Interface()).word
+		decoder.valueDecoder.Decode(newPtr, iter)
+		*((*uintptr)(ptr)) = uintptr(newPtr)
+	} else {
+		//reuse existing instance
+		decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
+	}
+}
+
+type optionalEncoder struct {
+	valueEncoder ValEncoder
+}
+
+func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	if *((*unsafe.Pointer)(ptr)) == nil {
+		stream.WriteNil()
+	} else {
+		encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
+	}
+}
+
+func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	if *((*unsafe.Pointer)(ptr)) == nil {
+		return true
+	}
+	return false
+}
+
+type placeholderEncoder struct {
+	cfg      *frozenConfig
+	cacheKey reflect.Type
+}
+
+func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.getRealEncoder().Encode(ptr, stream)
+}
+
+func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.getRealEncoder().IsEmpty(ptr)
+}
+
+func (encoder *placeholderEncoder) getRealEncoder() ValEncoder {
+	for i := 0; i < 30; i++ {
+		realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey)
+		_, isPlaceholder := realDecoder.(*placeholderEncoder)
+		if isPlaceholder {
+			time.Sleep(time.Second)
+		} else {
+			return realDecoder
+		}
+	}
+	panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey))
+}
+
+type placeholderDecoder struct {
+	cfg      *frozenConfig
+	cacheKey reflect.Type
+}
+
+func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	for i := 0; i < 30; i++ {
+		realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey)
+		_, isPlaceholder := realDecoder.(*placeholderDecoder)
+		if isPlaceholder {
+			time.Sleep(time.Second)
+		} else {
+			realDecoder.Decode(ptr, iter)
+			return
+		}
+	}
+	panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey))
+}
+
+// emptyInterface is the header for an interface{} value.
+type emptyInterface struct {
+	typ  unsafe.Pointer
+	word unsafe.Pointer
+}
+
+// emptyInterface is the header for an interface with method (not interface{})
+type nonEmptyInterface struct {
+	// see ../runtime/iface.go:/Itab
+	itab *struct {
+		ityp   unsafe.Pointer // static interface type
+		typ    unsafe.Pointer // dynamic concrete type
+		link   unsafe.Pointer
+		bad    int32
+		unused int32
+		fun    [100000]unsafe.Pointer // method table
+	}
+	word unsafe.Pointer
+}
+
+// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
+func (iter *Iterator) ReadVal(obj interface{}) {
+	typ := reflect.TypeOf(obj)
+	cacheKey := typ.Elem()
+	decoder, err := decoderOfType(iter.cfg, cacheKey)
+	if err != nil {
+		iter.Error = err
+		return
+	}
+	e := (*emptyInterface)(unsafe.Pointer(&obj))
+	decoder.Decode(e.word, iter)
+}
+
+// WriteVal copy the go interface into underlying JSON, same as json.Marshal
+func (stream *Stream) WriteVal(val interface{}) {
+	if nil == val {
+		stream.WriteNil()
+		return
+	}
+	typ := reflect.TypeOf(val)
+	cacheKey := typ
+	encoder, err := encoderOfType(stream.cfg, cacheKey)
+	if err != nil {
+		stream.Error = err
+		return
+	}
+	encoder.EncodeInterface(val, stream)
+}
+
+type prefix string
+
+func (p prefix) addToDecoder(decoder ValDecoder, err error) (ValDecoder, error) {
+	if err != nil {
+		return nil, fmt.Errorf("%s: %s", p, err.Error())
+	}
+	return decoder, err
+}
+
+func (p prefix) addToEncoder(encoder ValEncoder, err error) (ValEncoder, error) {
+	if err != nil {
+		return nil, fmt.Errorf("%s: %s", p, err.Error())
+	}
+	return encoder, err
+}
+
+func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
+	cacheKey := typ
+	decoder := cfg.getDecoderFromCache(cacheKey)
+	if decoder != nil {
+		return decoder, nil
+	}
+	decoder = getTypeDecoderFromExtension(typ)
+	if decoder != nil {
+		cfg.addDecoderToCache(cacheKey, decoder)
+		return decoder, nil
+	}
+	decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
+	cfg.addDecoderToCache(cacheKey, decoder)
+	decoder, err := createDecoderOfType(cfg, typ)
+	for _, extension := range extensions {
+		decoder = extension.DecorateDecoder(typ, decoder)
+	}
+	cfg.addDecoderToCache(cacheKey, decoder)
+	return decoder, err
+}
+
+func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
+	typeName := typ.String()
+	if typ == jsonRawMessageType {
+		return &jsonRawMessageCodec{}, nil
+	}
+	if typ == jsoniterRawMessageType {
+		return &jsoniterRawMessageCodec{}, nil
+	}
+	if typ.AssignableTo(jsonNumberType) {
+		return &jsonNumberCodec{}, nil
+	}
+	if typ.AssignableTo(jsoniterNumberType) {
+		return &jsoniterNumberCodec{}, nil
+	}
+	if typ.Implements(unmarshalerType) {
+		templateInterface := reflect.New(typ).Elem().Interface()
+		var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
+		if typ.Kind() == reflect.Ptr {
+			decoder = &optionalDecoder{typ.Elem(), decoder}
+		}
+		return decoder, nil
+	}
+	if reflect.PtrTo(typ).Implements(unmarshalerType) {
+		templateInterface := reflect.New(typ).Interface()
+		var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
+		return decoder, nil
+	}
+	if typ.Implements(textUnmarshalerType) {
+		templateInterface := reflect.New(typ).Elem().Interface()
+		var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
+		if typ.Kind() == reflect.Ptr {
+			decoder = &optionalDecoder{typ.Elem(), decoder}
+		}
+		return decoder, nil
+	}
+	if reflect.PtrTo(typ).Implements(textUnmarshalerType) {
+		templateInterface := reflect.New(typ).Interface()
+		var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
+		return decoder, nil
+	}
+	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
+		sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
+		if err != nil {
+			return nil, err
+		}
+		return &base64Codec{sliceDecoder: sliceDecoder}, nil
+	}
+	if typ.Implements(anyType) {
+		return &anyCodec{}, nil
+	}
+	switch typ.Kind() {
+	case reflect.String:
+		if typeName != "string" {
+			return decoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem())
+		}
+		return &stringCodec{}, nil
+	case reflect.Int:
+		if typeName != "int" {
+			return decoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem())
+		}
+		return &intCodec{}, nil
+	case reflect.Int8:
+		if typeName != "int8" {
+			return decoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem())
+		}
+		return &int8Codec{}, nil
+	case reflect.Int16:
+		if typeName != "int16" {
+			return decoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem())
+		}
+		return &int16Codec{}, nil
+	case reflect.Int32:
+		if typeName != "int32" {
+			return decoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem())
+		}
+		return &int32Codec{}, nil
+	case reflect.Int64:
+		if typeName != "int64" {
+			return decoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem())
+		}
+		return &int64Codec{}, nil
+	case reflect.Uint:
+		if typeName != "uint" {
+			return decoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem())
+		}
+		return &uintCodec{}, nil
+	case reflect.Uint8:
+		if typeName != "uint8" {
+			return decoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem())
+		}
+		return &uint8Codec{}, nil
+	case reflect.Uint16:
+		if typeName != "uint16" {
+			return decoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem())
+		}
+		return &uint16Codec{}, nil
+	case reflect.Uint32:
+		if typeName != "uint32" {
+			return decoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem())
+		}
+		return &uint32Codec{}, nil
+	case reflect.Uintptr:
+		if typeName != "uintptr" {
+			return decoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem())
+		}
+		return &uintptrCodec{}, nil
+	case reflect.Uint64:
+		if typeName != "uint64" {
+			return decoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem())
+		}
+		return &uint64Codec{}, nil
+	case reflect.Float32:
+		if typeName != "float32" {
+			return decoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem())
+		}
+		return &float32Codec{}, nil
+	case reflect.Float64:
+		if typeName != "float64" {
+			return decoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem())
+		}
+		return &float64Codec{}, nil
+	case reflect.Bool:
+		if typeName != "bool" {
+			return decoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem())
+		}
+		return &boolCodec{}, nil
+	case reflect.Interface:
+		if typ.NumMethod() == 0 {
+			return &emptyInterfaceCodec{}, nil
+		}
+		return &nonEmptyInterfaceCodec{}, nil
+	case reflect.Struct:
+		return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(cfg, typ))
+	case reflect.Array:
+		return prefix("[array]").addToDecoder(decoderOfArray(cfg, typ))
+	case reflect.Slice:
+		return prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
+	case reflect.Map:
+		return prefix("[map]").addToDecoder(decoderOfMap(cfg, typ))
+	case reflect.Ptr:
+		return prefix("[optional]").addToDecoder(decoderOfOptional(cfg, typ))
+	default:
+		return nil, fmt.Errorf("unsupported type: %v", typ)
+	}
+}
+
+func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
+	cacheKey := typ
+	encoder := cfg.getEncoderFromCache(cacheKey)
+	if encoder != nil {
+		return encoder, nil
+	}
+	encoder = getTypeEncoderFromExtension(typ)
+	if encoder != nil {
+		cfg.addEncoderToCache(cacheKey, encoder)
+		return encoder, nil
+	}
+	encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey}
+	cfg.addEncoderToCache(cacheKey, encoder)
+	encoder, err := createEncoderOfType(cfg, typ)
+	for _, extension := range extensions {
+		encoder = extension.DecorateEncoder(typ, encoder)
+	}
+	cfg.addEncoderToCache(cacheKey, encoder)
+	return encoder, err
+}
+
+func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
+	if typ == jsonRawMessageType {
+		return &jsonRawMessageCodec{}, nil
+	}
+	if typ == jsoniterRawMessageType {
+		return &jsoniterRawMessageCodec{}, nil
+	}
+	if typ.AssignableTo(jsonNumberType) {
+		return &jsonNumberCodec{}, nil
+	}
+	if typ.AssignableTo(jsoniterNumberType) {
+		return &jsoniterNumberCodec{}, nil
+	}
+	if typ.Implements(marshalerType) {
+		checkIsEmpty, err := createCheckIsEmpty(typ)
+		if err != nil {
+			return nil, err
+		}
+		templateInterface := reflect.New(typ).Elem().Interface()
+		var encoder ValEncoder = &marshalerEncoder{
+			templateInterface: extractInterface(templateInterface),
+			checkIsEmpty:      checkIsEmpty,
+		}
+		if typ.Kind() == reflect.Ptr {
+			encoder = &optionalEncoder{encoder}
+		}
+		return encoder, nil
+	}
+	if typ.Implements(textMarshalerType) {
+		checkIsEmpty, err := createCheckIsEmpty(typ)
+		if err != nil {
+			return nil, err
+		}
+		templateInterface := reflect.New(typ).Elem().Interface()
+		var encoder ValEncoder = &textMarshalerEncoder{
+			templateInterface: extractInterface(templateInterface),
+			checkIsEmpty:      checkIsEmpty,
+		}
+		if typ.Kind() == reflect.Ptr {
+			encoder = &optionalEncoder{encoder}
+		}
+		return encoder, nil
+	}
+	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
+		return &base64Codec{}, nil
+	}
+	if typ.Implements(anyType) {
+		return &anyCodec{}, nil
+	}
+	return createEncoderOfSimpleType(cfg, typ)
+}
+
+func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) {
+	kind := typ.Kind()
+	switch kind {
+	case reflect.String:
+		return &stringCodec{}, nil
+	case reflect.Int:
+		return &intCodec{}, nil
+	case reflect.Int8:
+		return &int8Codec{}, nil
+	case reflect.Int16:
+		return &int16Codec{}, nil
+	case reflect.Int32:
+		return &int32Codec{}, nil
+	case reflect.Int64:
+		return &int64Codec{}, nil
+	case reflect.Uint:
+		return &uintCodec{}, nil
+	case reflect.Uint8:
+		return &uint8Codec{}, nil
+	case reflect.Uint16:
+		return &uint16Codec{}, nil
+	case reflect.Uint32:
+		return &uint32Codec{}, nil
+	case reflect.Uintptr:
+		return &uintptrCodec{}, nil
+	case reflect.Uint64:
+		return &uint64Codec{}, nil
+	case reflect.Float32:
+		return &float32Codec{}, nil
+	case reflect.Float64:
+		return &float64Codec{}, nil
+	case reflect.Bool:
+		return &boolCodec{}, nil
+	case reflect.Interface:
+		if typ.NumMethod() == 0 {
+			return &emptyInterfaceCodec{}, nil
+		}
+		return &nonEmptyInterfaceCodec{}, nil
+	case reflect.Struct:
+		return &structEncoder{}, nil
+	case reflect.Array:
+		return &arrayEncoder{}, nil
+	case reflect.Slice:
+		return &sliceEncoder{}, nil
+	case reflect.Map:
+		return &mapEncoder{}, nil
+	case reflect.Ptr:
+		return &optionalEncoder{}, nil
+	default:
+		return nil, fmt.Errorf("unsupported type: %v", typ)
+	}
+}
+
+func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
+	typeName := typ.String()
+	kind := typ.Kind()
+	switch kind {
+	case reflect.String:
+		if typeName != "string" {
+			return encoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem())
+		}
+		return &stringCodec{}, nil
+	case reflect.Int:
+		if typeName != "int" {
+			return encoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem())
+		}
+		return &intCodec{}, nil
+	case reflect.Int8:
+		if typeName != "int8" {
+			return encoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem())
+		}
+		return &int8Codec{}, nil
+	case reflect.Int16:
+		if typeName != "int16" {
+			return encoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem())
+		}
+		return &int16Codec{}, nil
+	case reflect.Int32:
+		if typeName != "int32" {
+			return encoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem())
+		}
+		return &int32Codec{}, nil
+	case reflect.Int64:
+		if typeName != "int64" {
+			return encoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem())
+		}
+		return &int64Codec{}, nil
+	case reflect.Uint:
+		if typeName != "uint" {
+			return encoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem())
+		}
+		return &uintCodec{}, nil
+	case reflect.Uint8:
+		if typeName != "uint8" {
+			return encoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem())
+		}
+		return &uint8Codec{}, nil
+	case reflect.Uint16:
+		if typeName != "uint16" {
+			return encoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem())
+		}
+		return &uint16Codec{}, nil
+	case reflect.Uint32:
+		if typeName != "uint32" {
+			return encoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem())
+		}
+		return &uint32Codec{}, nil
+	case reflect.Uintptr:
+		if typeName != "uintptr" {
+			return encoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem())
+		}
+		return &uintptrCodec{}, nil
+	case reflect.Uint64:
+		if typeName != "uint64" {
+			return encoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem())
+		}
+		return &uint64Codec{}, nil
+	case reflect.Float32:
+		if typeName != "float32" {
+			return encoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem())
+		}
+		return &float32Codec{}, nil
+	case reflect.Float64:
+		if typeName != "float64" {
+			return encoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem())
+		}
+		return &float64Codec{}, nil
+	case reflect.Bool:
+		if typeName != "bool" {
+			return encoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem())
+		}
+		return &boolCodec{}, nil
+	case reflect.Interface:
+		if typ.NumMethod() == 0 {
+			return &emptyInterfaceCodec{}, nil
+		}
+		return &nonEmptyInterfaceCodec{}, nil
+	case reflect.Struct:
+		return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(cfg, typ))
+	case reflect.Array:
+		return prefix("[array]").addToEncoder(encoderOfArray(cfg, typ))
+	case reflect.Slice:
+		return prefix("[slice]").addToEncoder(encoderOfSlice(cfg, typ))
+	case reflect.Map:
+		return prefix("[map]").addToEncoder(encoderOfMap(cfg, typ))
+	case reflect.Ptr:
+		return prefix("[optional]").addToEncoder(encoderOfOptional(cfg, typ))
+	default:
+		return nil, fmt.Errorf("unsupported type: %v", typ)
+	}
+}
+
+func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
+	elemType := typ.Elem()
+	decoder, err := decoderOfType(cfg, elemType)
+	if err != nil {
+		return nil, err
+	}
+	return &optionalDecoder{elemType, decoder}, nil
+}
+
+func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
+	elemType := typ.Elem()
+	elemEncoder, err := encoderOfType(cfg, elemType)
+	if err != nil {
+		return nil, err
+	}
+	encoder := &optionalEncoder{elemEncoder}
+	if elemType.Kind() == reflect.Map {
+		encoder = &optionalEncoder{encoder}
+	}
+	return encoder, nil
+}
+
+func decoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
+	decoder, err := decoderOfType(cfg, typ.Elem())
+	if err != nil {
+		return nil, err
+	}
+	mapInterface := reflect.New(typ).Interface()
+	return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}, nil
+}
+
+func extractInterface(val interface{}) emptyInterface {
+	return *((*emptyInterface)(unsafe.Pointer(&val)))
+}
+
+func encoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
+	elemType := typ.Elem()
+	encoder, err := encoderOfType(cfg, elemType)
+	if err != nil {
+		return nil, err
+	}
+	mapInterface := reflect.New(typ).Elem().Interface()
+	if cfg.sortMapKeys {
+		return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
+	}
+	return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
+}
diff --git a/vendor/github.com/json-iterator/go/feature_reflect_array.go b/vendor/github.com/json-iterator/go/feature_reflect_array.go
new file mode 100644
index 000000000..e23f187b7
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_reflect_array.go
@@ -0,0 +1,99 @@
+package jsoniter
+
+import (
+	"fmt"
+	"io"
+	"reflect"
+	"unsafe"
+)
+
+func decoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
+	decoder, err := decoderOfType(cfg, typ.Elem())
+	if err != nil {
+		return nil, err
+	}
+	return &arrayDecoder{typ, typ.Elem(), decoder}, nil
+}
+
+func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
+	encoder, err := encoderOfType(cfg, typ.Elem())
+	if err != nil {
+		return nil, err
+	}
+	if typ.Elem().Kind() == reflect.Map {
+		encoder = &optionalEncoder{encoder}
+	}
+	return &arrayEncoder{typ, typ.Elem(), encoder}, nil
+}
+
+type arrayEncoder struct {
+	arrayType   reflect.Type
+	elemType    reflect.Type
+	elemEncoder ValEncoder
+}
+
+func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteArrayStart()
+	elemPtr := unsafe.Pointer(ptr)
+	encoder.elemEncoder.Encode(elemPtr, stream)
+	for i := 1; i < encoder.arrayType.Len(); i++ {
+		stream.WriteMore()
+		elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
+		encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
+	}
+	stream.WriteArrayEnd()
+	if stream.Error != nil && stream.Error != io.EOF {
+		stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
+	}
+}
+
+func (encoder *arrayEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	// special optimization for interface{}
+	e := (*emptyInterface)(unsafe.Pointer(&val))
+	if e.word == nil {
+		stream.WriteArrayStart()
+		stream.WriteNil()
+		stream.WriteArrayEnd()
+		return
+	}
+	elemType := encoder.arrayType.Elem()
+	if encoder.arrayType.Len() == 1 && (elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map) {
+		ptr := uintptr(e.word)
+		e.word = unsafe.Pointer(&ptr)
+	}
+	if reflect.TypeOf(val).Kind() == reflect.Ptr {
+		encoder.Encode(unsafe.Pointer(&e.word), stream)
+	} else {
+		encoder.Encode(e.word, stream)
+	}
+}
+
+func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
+}
+
+type arrayDecoder struct {
+	arrayType   reflect.Type
+	elemType    reflect.Type
+	elemDecoder ValDecoder
+}
+
+func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.doDecode(ptr, iter)
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
+	}
+}
+
+func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
+	offset := uintptr(0)
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		if offset < decoder.arrayType.Size() {
+			decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter)
+			offset += decoder.elemType.Size()
+		} else {
+			iter.Skip()
+		}
+		return true
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/reflect_extension.go b/vendor/github.com/json-iterator/go/feature_reflect_extension.go
similarity index 53%
rename from vendor/github.com/json-iterator/go/reflect_extension.go
rename to vendor/github.com/json-iterator/go/feature_reflect_extension.go
index 04f68756b..3dd38299d 100644
--- a/vendor/github.com/json-iterator/go/reflect_extension.go
+++ b/vendor/github.com/json-iterator/go/feature_reflect_extension.go
@@ -2,7 +2,6 @@ package jsoniter
 
 import (
 	"fmt"
-	"github.com/modern-go/reflect2"
 	"reflect"
 	"sort"
 	"strings"
@@ -18,15 +17,17 @@ var extensions = []Extension{}
 
 // StructDescriptor describe how should we encode/decode the struct
 type StructDescriptor struct {
-	Type   reflect2.Type
-	Fields []*Binding
+	onePtrEmbedded     bool
+	onePtrOptimization bool
+	Type               reflect.Type
+	Fields             []*Binding
 }
 
 // GetField get one field from the descriptor by its name.
 // Can not use map here to keep field orders.
 func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
 	for _, binding := range structDescriptor.Fields {
-		if binding.Field.Name() == fieldName {
+		if binding.Field.Name == fieldName {
 			return binding
 		}
 	}
@@ -36,7 +37,7 @@ func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
 // Binding describe how should we encode/decode the struct field
 type Binding struct {
 	levels    []int
-	Field     reflect2.StructField
+	Field     *reflect.StructField
 	FromNames []string
 	ToNames   []string
 	Encoder   ValEncoder
@@ -47,12 +48,10 @@ type Binding struct {
 // Can also rename fields by UpdateStructDescriptor.
 type Extension interface {
 	UpdateStructDescriptor(structDescriptor *StructDescriptor)
-	CreateMapKeyDecoder(typ reflect2.Type) ValDecoder
-	CreateMapKeyEncoder(typ reflect2.Type) ValEncoder
-	CreateDecoder(typ reflect2.Type) ValDecoder
-	CreateEncoder(typ reflect2.Type) ValEncoder
-	DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder
-	DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder
+	CreateDecoder(typ reflect.Type) ValDecoder
+	CreateEncoder(typ reflect.Type) ValEncoder
+	DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder
+	DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder
 }
 
 // DummyExtension embed this type get dummy implementation for all methods of Extension
@@ -63,105 +62,23 @@ type DummyExtension struct {
 func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
 }
 
-// CreateMapKeyDecoder No-op
-func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
-	return nil
-}
-
-// CreateMapKeyEncoder No-op
-func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
-	return nil
-}
-
-// CreateDecoder No-op
-func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
-	return nil
-}
-
-// CreateEncoder No-op
-func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
-	return nil
-}
-
-// DecorateDecoder No-op
-func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
-	return decoder
-}
-
-// DecorateEncoder No-op
-func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
-	return encoder
-}
-
-type EncoderExtension map[reflect2.Type]ValEncoder
-
-// UpdateStructDescriptor No-op
-func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
-}
-
 // CreateDecoder No-op
-func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
-	return nil
-}
-
-// CreateEncoder get encoder from map
-func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
-	return extension[typ]
-}
-
-// CreateMapKeyDecoder No-op
-func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
-	return nil
-}
-
-// CreateMapKeyEncoder No-op
-func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
-	return nil
-}
-
-// DecorateDecoder No-op
-func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
-	return decoder
-}
-
-// DecorateEncoder No-op
-func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
-	return encoder
-}
-
-type DecoderExtension map[reflect2.Type]ValDecoder
-
-// UpdateStructDescriptor No-op
-func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
-}
-
-// CreateMapKeyDecoder No-op
-func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
-	return nil
-}
-
-// CreateMapKeyEncoder No-op
-func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
+func (extension *DummyExtension) CreateDecoder(typ reflect.Type) ValDecoder {
 	return nil
 }
 
-// CreateDecoder get decoder from map
-func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
-	return extension[typ]
-}
-
 // CreateEncoder No-op
-func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
+func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder {
 	return nil
 }
 
 // DecorateDecoder No-op
-func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
+func (extension *DummyExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder {
 	return decoder
 }
 
 // DecorateEncoder No-op
-func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
+func (extension *DummyExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder {
 	return encoder
 }
 
@@ -182,6 +99,10 @@ func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	encoder.fun(ptr, stream)
 }
 
+func (encoder *funcEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
 func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	if encoder.isEmptyFunc == nil {
 		return false
@@ -240,151 +161,132 @@ func RegisterExtension(extension Extension) {
 	extensions = append(extensions, extension)
 }
 
-func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
-	decoder := _getTypeDecoderFromExtension(ctx, typ)
+func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
+	decoder := _getTypeDecoderFromExtension(typ)
 	if decoder != nil {
 		for _, extension := range extensions {
 			decoder = extension.DecorateDecoder(typ, decoder)
 		}
-		decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder)
-		for _, extension := range ctx.extraExtensions {
-			decoder = extension.DecorateDecoder(typ, decoder)
-		}
 	}
 	return decoder
 }
-func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
+func _getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
 	for _, extension := range extensions {
 		decoder := extension.CreateDecoder(typ)
 		if decoder != nil {
 			return decoder
 		}
 	}
-	decoder := ctx.decoderExtension.CreateDecoder(typ)
-	if decoder != nil {
-		return decoder
-	}
-	for _, extension := range ctx.extraExtensions {
-		decoder := extension.CreateDecoder(typ)
-		if decoder != nil {
-			return decoder
-		}
-	}
 	typeName := typ.String()
-	decoder = typeDecoders[typeName]
+	decoder := typeDecoders[typeName]
 	if decoder != nil {
 		return decoder
 	}
 	if typ.Kind() == reflect.Ptr {
-		ptrType := typ.(*reflect2.UnsafePtrType)
-		decoder := typeDecoders[ptrType.Elem().String()]
+		decoder := typeDecoders[typ.Elem().String()]
 		if decoder != nil {
-			return &OptionalDecoder{ptrType.Elem(), decoder}
+			return &optionalDecoder{typ.Elem(), decoder}
 		}
 	}
 	return nil
 }
 
-func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
-	encoder := _getTypeEncoderFromExtension(ctx, typ)
+func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
+	encoder := _getTypeEncoderFromExtension(typ)
 	if encoder != nil {
 		for _, extension := range extensions {
 			encoder = extension.DecorateEncoder(typ, encoder)
 		}
-		encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder)
-		for _, extension := range ctx.extraExtensions {
-			encoder = extension.DecorateEncoder(typ, encoder)
-		}
 	}
 	return encoder
 }
 
-func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
+func _getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
 	for _, extension := range extensions {
 		encoder := extension.CreateEncoder(typ)
 		if encoder != nil {
 			return encoder
 		}
 	}
-	encoder := ctx.encoderExtension.CreateEncoder(typ)
-	if encoder != nil {
-		return encoder
-	}
-	for _, extension := range ctx.extraExtensions {
-		encoder := extension.CreateEncoder(typ)
-		if encoder != nil {
-			return encoder
-		}
-	}
 	typeName := typ.String()
-	encoder = typeEncoders[typeName]
+	encoder := typeEncoders[typeName]
 	if encoder != nil {
 		return encoder
 	}
 	if typ.Kind() == reflect.Ptr {
-		typePtr := typ.(*reflect2.UnsafePtrType)
-		encoder := typeEncoders[typePtr.Elem().String()]
+		encoder := typeEncoders[typ.Elem().String()]
 		if encoder != nil {
-			return &OptionalEncoder{encoder}
+			return &optionalEncoder{encoder}
 		}
 	}
 	return nil
 }
 
-func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
-	structType := typ.(*reflect2.UnsafeStructType)
+func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) {
 	embeddedBindings := []*Binding{}
 	bindings := []*Binding{}
-	for i := 0; i < structType.NumField(); i++ {
-		field := structType.Field(i)
-		tag, hastag := field.Tag().Lookup(ctx.getTagKey())
-		if ctx.onlyTaggedField && !hastag {
-			continue
-		}
+	for i := 0; i < typ.NumField(); i++ {
+		field := typ.Field(i)
+		tag := field.Tag.Get(cfg.getTagKey())
 		tagParts := strings.Split(tag, ",")
 		if tag == "-" {
 			continue
 		}
-		if field.Anonymous() && (tag == "" || tagParts[0] == "") {
-			if field.Type().Kind() == reflect.Struct {
-				structDescriptor := describeStruct(ctx, field.Type())
+		if field.Anonymous && (tag == "" || tagParts[0] == "") {
+			if field.Type.Kind() == reflect.Struct {
+				structDescriptor, err := describeStruct(cfg, field.Type)
+				if err != nil {
+					return nil, err
+				}
 				for _, binding := range structDescriptor.Fields {
 					binding.levels = append([]int{i}, binding.levels...)
 					omitempty := binding.Encoder.(*structFieldEncoder).omitempty
-					binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
-					binding.Decoder = &structFieldDecoder{field, binding.Decoder}
+					binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
+					binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
 					embeddedBindings = append(embeddedBindings, binding)
 				}
 				continue
-			} else if field.Type().Kind() == reflect.Ptr {
-				ptrType := field.Type().(*reflect2.UnsafePtrType)
-				if ptrType.Elem().Kind() == reflect.Struct {
-					structDescriptor := describeStruct(ctx, ptrType.Elem())
-					for _, binding := range structDescriptor.Fields {
-						binding.levels = append([]int{i}, binding.levels...)
-						omitempty := binding.Encoder.(*structFieldEncoder).omitempty
-						binding.Encoder = &dereferenceEncoder{binding.Encoder}
-						binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
-						binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder}
-						binding.Decoder = &structFieldDecoder{field, binding.Decoder}
-						embeddedBindings = append(embeddedBindings, binding)
-					}
-					continue
+			} else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
+				structDescriptor, err := describeStruct(cfg, field.Type.Elem())
+				if err != nil {
+					return nil, err
 				}
+				for _, binding := range structDescriptor.Fields {
+					binding.levels = append([]int{i}, binding.levels...)
+					omitempty := binding.Encoder.(*structFieldEncoder).omitempty
+					binding.Encoder = &optionalEncoder{binding.Encoder}
+					binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
+					binding.Decoder = &deferenceDecoder{field.Type.Elem(), binding.Decoder}
+					binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
+					embeddedBindings = append(embeddedBindings, binding)
+				}
+				continue
 			}
 		}
-		fieldNames := calcFieldNames(field.Name(), tagParts[0], tag)
-		fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name())
+		fieldNames := calcFieldNames(field.Name, tagParts[0], tag)
+		fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
 		decoder := fieldDecoders[fieldCacheKey]
 		if decoder == nil {
-			decoder = decoderOfType(ctx.append(field.Name()), field.Type())
+			var err error
+			decoder, err = decoderOfType(cfg, field.Type)
+			if err != nil {
+				return nil, err
+			}
 		}
 		encoder := fieldEncoders[fieldCacheKey]
 		if encoder == nil {
-			encoder = encoderOfType(ctx.append(field.Name()), field.Type())
+			var err error
+			encoder, err = encoderOfType(cfg, field.Type)
+			if err != nil {
+				return nil, err
+			}
+			// map is stored as pointer in the struct
+			if field.Type.Kind() == reflect.Map {
+				encoder = &optionalEncoder{encoder}
+			}
 		}
 		binding := &Binding{
-			Field:     field,
+			Field:     &field,
 			FromNames: fieldNames,
 			ToNames:   fieldNames,
 			Decoder:   decoder,
@@ -393,22 +295,35 @@ func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
 		binding.levels = []int{i}
 		bindings = append(bindings, binding)
 	}
-	return createStructDescriptor(ctx, typ, bindings, embeddedBindings)
-}
-func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
+	return createStructDescriptor(cfg, typ, bindings, embeddedBindings), nil
+}
+func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
+	onePtrEmbedded := false
+	onePtrOptimization := false
+	if typ.NumField() == 1 {
+		firstField := typ.Field(0)
+		switch firstField.Type.Kind() {
+		case reflect.Ptr:
+			if firstField.Anonymous && firstField.Type.Elem().Kind() == reflect.Struct {
+				onePtrEmbedded = true
+			}
+			fallthrough
+		case reflect.Map:
+			onePtrOptimization = true
+		case reflect.Struct:
+			onePtrOptimization = isStructOnePtr(firstField.Type)
+		}
+	}
 	structDescriptor := &StructDescriptor{
-		Type:   typ,
-		Fields: bindings,
+		onePtrEmbedded:     onePtrEmbedded,
+		onePtrOptimization: onePtrOptimization,
+		Type:               typ,
+		Fields:             bindings,
 	}
 	for _, extension := range extensions {
 		extension.UpdateStructDescriptor(structDescriptor)
 	}
-	ctx.encoderExtension.UpdateStructDescriptor(structDescriptor)
-	ctx.decoderExtension.UpdateStructDescriptor(structDescriptor)
-	for _, extension := range ctx.extraExtensions {
-		extension.UpdateStructDescriptor(structDescriptor)
-	}
-	processTags(structDescriptor, ctx.frozenConfig)
+	processTags(structDescriptor, cfg)
 	// merge normal & embedded bindings & sort with original order
 	allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))
 	sort.Sort(allBindings)
@@ -416,6 +331,21 @@ func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, em
 	return structDescriptor
 }
 
+func isStructOnePtr(typ reflect.Type) bool {
+	if typ.NumField() == 1 {
+		firstField := typ.Field(0)
+		switch firstField.Type.Kind() {
+		case reflect.Ptr:
+			return true
+		case reflect.Map:
+			return true
+		case reflect.Struct:
+			return isStructOnePtr(firstField.Type)
+		}
+	}
+	return false
+}
+
 type sortableBindings []*Binding
 
 func (bindings sortableBindings) Len() int {
@@ -443,12 +373,12 @@ func (bindings sortableBindings) Swap(i, j int) {
 func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) {
 	for _, binding := range structDescriptor.Fields {
 		shouldOmitEmpty := false
-		tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",")
+		tagParts := strings.Split(binding.Field.Tag.Get(cfg.getTagKey()), ",")
 		for _, tagPart := range tagParts[1:] {
 			if tagPart == "omitempty" {
 				shouldOmitEmpty = true
 			} else if tagPart == "string" {
-				if binding.Field.Type().Kind() == reflect.String {
+				if binding.Field.Type.Kind() == reflect.String {
 					binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg}
 					binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg}
 				} else {
diff --git a/vendor/github.com/json-iterator/go/feature_reflect_map.go b/vendor/github.com/json-iterator/go/feature_reflect_map.go
new file mode 100644
index 000000000..005671e01
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_reflect_map.go
@@ -0,0 +1,244 @@
+package jsoniter
+
+import (
+	"encoding"
+	"encoding/json"
+	"reflect"
+	"sort"
+	"strconv"
+	"unsafe"
+)
+
+type mapDecoder struct {
+	mapType      reflect.Type
+	keyType      reflect.Type
+	elemType     reflect.Type
+	elemDecoder  ValDecoder
+	mapInterface emptyInterface
+}
+
+func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	// dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
+	mapInterface := decoder.mapInterface
+	mapInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
+	realVal := reflect.ValueOf(*realInterface).Elem()
+	if iter.ReadNil() {
+		realVal.Set(reflect.Zero(decoder.mapType))
+		return
+	}
+	if realVal.IsNil() {
+		realVal.Set(reflect.MakeMap(realVal.Type()))
+	}
+	iter.ReadMapCB(func(iter *Iterator, keyStr string) bool {
+		elem := reflect.New(decoder.elemType)
+		decoder.elemDecoder.Decode(unsafe.Pointer(elem.Pointer()), iter)
+		// to put into map, we have to use reflection
+		keyType := decoder.keyType
+		// TODO: remove this from loop
+		switch {
+		case keyType.Kind() == reflect.String:
+			realVal.SetMapIndex(reflect.ValueOf(keyStr).Convert(keyType), elem.Elem())
+			return true
+		case keyType.Implements(textUnmarshalerType):
+			textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler)
+			err := textUnmarshaler.UnmarshalText([]byte(keyStr))
+			if err != nil {
+				iter.ReportError("read map key as TextUnmarshaler", err.Error())
+				return false
+			}
+			realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem())
+			return true
+		case reflect.PtrTo(keyType).Implements(textUnmarshalerType):
+			textUnmarshaler := reflect.New(keyType).Interface().(encoding.TextUnmarshaler)
+			err := textUnmarshaler.UnmarshalText([]byte(keyStr))
+			if err != nil {
+				iter.ReportError("read map key as TextUnmarshaler", err.Error())
+				return false
+			}
+			realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler).Elem(), elem.Elem())
+			return true
+		default:
+			switch keyType.Kind() {
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				n, err := strconv.ParseInt(keyStr, 10, 64)
+				if err != nil || reflect.Zero(keyType).OverflowInt(n) {
+					iter.ReportError("read map key as int64", "read int64 failed")
+					return false
+				}
+				realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
+				return true
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+				n, err := strconv.ParseUint(keyStr, 10, 64)
+				if err != nil || reflect.Zero(keyType).OverflowUint(n) {
+					iter.ReportError("read map key as uint64", "read uint64 failed")
+					return false
+				}
+				realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
+				return true
+			}
+		}
+		iter.ReportError("read map key", "unexpected map key type "+keyType.String())
+		return true
+	})
+}
+
+type mapEncoder struct {
+	mapType      reflect.Type
+	elemType     reflect.Type
+	elemEncoder  ValEncoder
+	mapInterface emptyInterface
+}
+
+func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	mapInterface := encoder.mapInterface
+	mapInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
+	realVal := reflect.ValueOf(*realInterface)
+	stream.WriteObjectStart()
+	for i, key := range realVal.MapKeys() {
+		if i != 0 {
+			stream.WriteMore()
+		}
+		encodeMapKey(key, stream)
+		if stream.indention > 0 {
+			stream.writeTwoBytes(byte(':'), byte(' '))
+		} else {
+			stream.writeByte(':')
+		}
+		val := realVal.MapIndex(key).Interface()
+		encoder.elemEncoder.EncodeInterface(val, stream)
+	}
+	stream.WriteObjectEnd()
+}
+
+func encodeMapKey(key reflect.Value, stream *Stream) {
+	if key.Kind() == reflect.String {
+		stream.WriteString(key.String())
+		return
+	}
+	if tm, ok := key.Interface().(encoding.TextMarshaler); ok {
+		buf, err := tm.MarshalText()
+		if err != nil {
+			stream.Error = err
+			return
+		}
+		stream.writeByte('"')
+		stream.Write(buf)
+		stream.writeByte('"')
+		return
+	}
+	switch key.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		stream.writeByte('"')
+		stream.WriteInt64(key.Int())
+		stream.writeByte('"')
+		return
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		stream.writeByte('"')
+		stream.WriteUint64(key.Uint())
+		stream.writeByte('"')
+		return
+	}
+	stream.Error = &json.UnsupportedTypeError{Type: key.Type()}
+}
+
+func (encoder *mapEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	mapInterface := encoder.mapInterface
+	mapInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
+	realVal := reflect.ValueOf(*realInterface)
+	return realVal.Len() == 0
+}
+
+type sortKeysMapEncoder struct {
+	mapType      reflect.Type
+	elemType     reflect.Type
+	elemEncoder  ValEncoder
+	mapInterface emptyInterface
+}
+
+func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	mapInterface := encoder.mapInterface
+	mapInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
+	realVal := reflect.ValueOf(*realInterface)
+
+	// Extract and sort the keys.
+	keys := realVal.MapKeys()
+	sv := stringValues(make([]reflectWithString, len(keys)))
+	for i, v := range keys {
+		sv[i].v = v
+		if err := sv[i].resolve(); err != nil {
+			stream.Error = err
+			return
+		}
+	}
+	sort.Sort(sv)
+
+	stream.WriteObjectStart()
+	for i, key := range sv {
+		if i != 0 {
+			stream.WriteMore()
+		}
+		stream.WriteVal(key.s) // might need html escape, so can not WriteString directly
+		if stream.indention > 0 {
+			stream.writeTwoBytes(byte(':'), byte(' '))
+		} else {
+			stream.writeByte(':')
+		}
+		val := realVal.MapIndex(key.v).Interface()
+		encoder.elemEncoder.EncodeInterface(val, stream)
+	}
+	stream.WriteObjectEnd()
+}
+
+// stringValues is a slice of reflect.Value holding *reflect.StringValue.
+// It implements the methods to sort by string.
+type stringValues []reflectWithString
+
+type reflectWithString struct {
+	v reflect.Value
+	s string
+}
+
+func (w *reflectWithString) resolve() error {
+	if w.v.Kind() == reflect.String {
+		w.s = w.v.String()
+		return nil
+	}
+	if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
+		buf, err := tm.MarshalText()
+		w.s = string(buf)
+		return err
+	}
+	switch w.v.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		w.s = strconv.FormatInt(w.v.Int(), 10)
+		return nil
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		w.s = strconv.FormatUint(w.v.Uint(), 10)
+		return nil
+	}
+	return &json.UnsupportedTypeError{Type: w.v.Type()}
+}
+
+func (sv stringValues) Len() int           { return len(sv) }
+func (sv stringValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
+func (sv stringValues) Less(i, j int) bool { return sv[i].s < sv[j].s }
+
+func (encoder *sortKeysMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	mapInterface := encoder.mapInterface
+	mapInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
+	realVal := reflect.ValueOf(*realInterface)
+	return realVal.Len() == 0
+}
diff --git a/vendor/github.com/json-iterator/go/feature_reflect_native.go b/vendor/github.com/json-iterator/go/feature_reflect_native.go
new file mode 100644
index 000000000..b37dab3d8
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_reflect_native.go
@@ -0,0 +1,672 @@
+package jsoniter
+
+import (
+	"encoding"
+	"encoding/base64"
+	"encoding/json"
+	"unsafe"
+)
+
+type stringCodec struct {
+}
+
+func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*string)(ptr)) = iter.ReadString()
+}
+
+func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	str := *((*string)(ptr))
+	stream.WriteString(str)
+}
+
+func (codec *stringCodec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*string)(ptr)) == ""
+}
+
+type intCodec struct {
+}
+
+func (codec *intCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*int)(ptr)) = iter.ReadInt()
+}
+
+func (codec *intCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt(*((*int)(ptr)))
+}
+
+func (codec *intCodec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *intCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int)(ptr)) == 0
+}
+
+type uintptrCodec struct {
+}
+
+func (codec *uintptrCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*uintptr)(ptr)) = uintptr(iter.ReadUint64())
+}
+
+func (codec *uintptrCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint64(uint64(*((*uintptr)(ptr))))
+}
+
+func (codec *uintptrCodec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *uintptrCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uintptr)(ptr)) == 0
+}
+
+type int8Codec struct {
+}
+
+func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*int8)(ptr)) = iter.ReadInt8()
+}
+
+func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt8(*((*int8)(ptr)))
+}
+
+func (codec *int8Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int8)(ptr)) == 0
+}
+
+type int16Codec struct {
+}
+
+func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*int16)(ptr)) = iter.ReadInt16()
+}
+
+func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt16(*((*int16)(ptr)))
+}
+
+func (codec *int16Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int16)(ptr)) == 0
+}
+
+type int32Codec struct {
+}
+
+func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*int32)(ptr)) = iter.ReadInt32()
+}
+
+func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt32(*((*int32)(ptr)))
+}
+
+func (codec *int32Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int32)(ptr)) == 0
+}
+
+type int64Codec struct {
+}
+
+func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*int64)(ptr)) = iter.ReadInt64()
+}
+
+func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt64(*((*int64)(ptr)))
+}
+
+func (codec *int64Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int64)(ptr)) == 0
+}
+
+type uintCodec struct {
+}
+
+func (codec *uintCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*uint)(ptr)) = iter.ReadUint()
+}
+
+func (codec *uintCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint(*((*uint)(ptr)))
+}
+
+func (codec *uintCodec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *uintCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint)(ptr)) == 0
+}
+
+type uint8Codec struct {
+}
+
+func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*uint8)(ptr)) = iter.ReadUint8()
+}
+
+func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint8(*((*uint8)(ptr)))
+}
+
+func (codec *uint8Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint8)(ptr)) == 0
+}
+
+type uint16Codec struct {
+}
+
+func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*uint16)(ptr)) = iter.ReadUint16()
+}
+
+func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint16(*((*uint16)(ptr)))
+}
+
+func (codec *uint16Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint16)(ptr)) == 0
+}
+
+type uint32Codec struct {
+}
+
+func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*uint32)(ptr)) = iter.ReadUint32()
+}
+
+func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint32(*((*uint32)(ptr)))
+}
+
+func (codec *uint32Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint32)(ptr)) == 0
+}
+
+type uint64Codec struct {
+}
+
+func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*uint64)(ptr)) = iter.ReadUint64()
+}
+
+func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint64(*((*uint64)(ptr)))
+}
+
+func (codec *uint64Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint64)(ptr)) == 0
+}
+
+type float32Codec struct {
+}
+
+func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*float32)(ptr)) = iter.ReadFloat32()
+}
+
+func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat32(*((*float32)(ptr)))
+}
+
+func (codec *float32Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float32)(ptr)) == 0
+}
+
+type float64Codec struct {
+}
+
+func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*float64)(ptr)) = iter.ReadFloat64()
+}
+
+func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat64(*((*float64)(ptr)))
+}
+
+func (codec *float64Codec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float64)(ptr)) == 0
+}
+
+type boolCodec struct {
+}
+
+func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*bool)(ptr)) = iter.ReadBool()
+}
+
+func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteBool(*((*bool)(ptr)))
+}
+
+func (codec *boolCodec) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, codec)
+}
+
+func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return !(*((*bool)(ptr)))
+}
+
+type emptyInterfaceCodec struct {
+}
+
+func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*interface{})(ptr)) = iter.Read()
+}
+
+func (codec *emptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteVal(*((*interface{})(ptr)))
+}
+
+func (codec *emptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) {
+	stream.WriteVal(val)
+}
+
+func (codec *emptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return ptr == nil
+}
+
+type nonEmptyInterfaceCodec struct {
+}
+
+func (codec *nonEmptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	nonEmptyInterface := (*nonEmptyInterface)(ptr)
+	if nonEmptyInterface.itab == nil {
+		iter.ReportError("read non-empty interface", "do not know which concrete type to decode to")
+		return
+	}
+	var i interface{}
+	e := (*emptyInterface)(unsafe.Pointer(&i))
+	e.typ = nonEmptyInterface.itab.typ
+	e.word = nonEmptyInterface.word
+	iter.ReadVal(&i)
+	nonEmptyInterface.word = e.word
+}
+
+func (codec *nonEmptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	nonEmptyInterface := (*nonEmptyInterface)(ptr)
+	var i interface{}
+	e := (*emptyInterface)(unsafe.Pointer(&i))
+	e.typ = nonEmptyInterface.itab.typ
+	e.word = nonEmptyInterface.word
+	stream.WriteVal(i)
+}
+
+func (codec *nonEmptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) {
+	stream.WriteVal(val)
+}
+
+func (codec *nonEmptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	nonEmptyInterface := (*nonEmptyInterface)(ptr)
+	return nonEmptyInterface.word == nil
+}
+
+type anyCodec struct {
+}
+
+func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*Any)(ptr)) = iter.ReadAny()
+}
+
+func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	(*((*Any)(ptr))).WriteTo(stream)
+}
+
+func (codec *anyCodec) EncodeInterface(val interface{}, stream *Stream) {
+	(val.(Any)).WriteTo(stream)
+}
+
+func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return (*((*Any)(ptr))).Size() == 0
+}
+
+type jsonNumberCodec struct {
+}
+
+func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
+}
+
+func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*json.Number)(ptr))))
+}
+
+func (codec *jsonNumberCodec) EncodeInterface(val interface{}, stream *Stream) {
+	stream.WriteRaw(string(val.(json.Number)))
+}
+
+func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*json.Number)(ptr))) == 0
+}
+
+type jsoniterNumberCodec struct {
+}
+
+func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
+}
+
+func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*Number)(ptr))))
+}
+
+func (codec *jsoniterNumberCodec) EncodeInterface(val interface{}, stream *Stream) {
+	stream.WriteRaw(string(val.(Number)))
+}
+
+func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*Number)(ptr))) == 0
+}
+
+type jsonRawMessageCodec struct {
+}
+
+func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
+}
+
+func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
+}
+
+func (codec *jsonRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) {
+	stream.WriteRaw(string(val.(json.RawMessage)))
+}
+
+func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*json.RawMessage)(ptr))) == 0
+}
+
+type jsoniterRawMessageCodec struct {
+}
+
+func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
+}
+
+func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*RawMessage)(ptr))))
+}
+
+func (codec *jsoniterRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) {
+	stream.WriteRaw(string(val.(RawMessage)))
+}
+
+func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*RawMessage)(ptr))) == 0
+}
+
+type base64Codec struct {
+	sliceDecoder ValDecoder
+}
+
+func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if iter.ReadNil() {
+		ptrSlice := (*sliceHeader)(ptr)
+		ptrSlice.Len = 0
+		ptrSlice.Cap = 0
+		ptrSlice.Data = nil
+		return
+	}
+	switch iter.WhatIsNext() {
+	case StringValue:
+		encoding := base64.StdEncoding
+		src := iter.SkipAndReturnBytes()
+		src = src[1 : len(src)-1]
+		decodedLen := encoding.DecodedLen(len(src))
+		dst := make([]byte, decodedLen)
+		len, err := encoding.Decode(dst, src)
+		if err != nil {
+			iter.ReportError("decode base64", err.Error())
+		} else {
+			dst = dst[:len]
+			dstSlice := (*sliceHeader)(unsafe.Pointer(&dst))
+			ptrSlice := (*sliceHeader)(ptr)
+			ptrSlice.Data = dstSlice.Data
+			ptrSlice.Cap = dstSlice.Cap
+			ptrSlice.Len = dstSlice.Len
+		}
+	case ArrayValue:
+		codec.sliceDecoder.Decode(ptr, iter)
+	default:
+		iter.ReportError("base64Codec", "invalid input")
+	}
+}
+
+func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	src := *((*[]byte)(ptr))
+	if len(src) == 0 {
+		stream.WriteNil()
+		return
+	}
+	encoding := base64.StdEncoding
+	stream.writeByte('"')
+	toGrow := encoding.EncodedLen(len(src))
+	stream.ensure(toGrow)
+	encoding.Encode(stream.buf[stream.n:], src)
+	stream.n += toGrow
+	stream.writeByte('"')
+}
+
+func (codec *base64Codec) EncodeInterface(val interface{}, stream *Stream) {
+	ptr := extractInterface(val).word
+	src := *((*[]byte)(ptr))
+	if len(src) == 0 {
+		stream.WriteNil()
+		return
+	}
+	encoding := base64.StdEncoding
+	stream.writeByte('"')
+	toGrow := encoding.EncodedLen(len(src))
+	stream.ensure(toGrow)
+	encoding.Encode(stream.buf[stream.n:], src)
+	stream.n += toGrow
+	stream.writeByte('"')
+}
+
+func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*[]byte)(ptr))) == 0
+}
+
+type stringModeNumberDecoder struct {
+	elemDecoder ValDecoder
+}
+
+func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	c := iter.nextToken()
+	if c != '"' {
+		iter.ReportError("stringModeNumberDecoder", `expect "`)
+		return
+	}
+	decoder.elemDecoder.Decode(ptr, iter)
+	if iter.Error != nil {
+		return
+	}
+	c = iter.readByte()
+	if c != '"' {
+		iter.ReportError("stringModeNumberDecoder", `expect "`)
+		return
+	}
+}
+
+type stringModeStringDecoder struct {
+	elemDecoder ValDecoder
+	cfg         *frozenConfig
+}
+
+func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.elemDecoder.Decode(ptr, iter)
+	str := *((*string)(ptr))
+	tempIter := decoder.cfg.BorrowIterator([]byte(str))
+	defer decoder.cfg.ReturnIterator(tempIter)
+	*((*string)(ptr)) = tempIter.ReadString()
+}
+
+type stringModeNumberEncoder struct {
+	elemEncoder ValEncoder
+}
+
+func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.writeByte('"')
+	encoder.elemEncoder.Encode(ptr, stream)
+	stream.writeByte('"')
+}
+
+func (encoder *stringModeNumberEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.elemEncoder.IsEmpty(ptr)
+}
+
+type stringModeStringEncoder struct {
+	elemEncoder ValEncoder
+	cfg         *frozenConfig
+}
+
+func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	tempStream := encoder.cfg.BorrowStream(nil)
+	defer encoder.cfg.ReturnStream(tempStream)
+	encoder.elemEncoder.Encode(ptr, tempStream)
+	stream.WriteString(string(tempStream.Buffer()))
+}
+
+func (encoder *stringModeStringEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.elemEncoder.IsEmpty(ptr)
+}
+
+type marshalerEncoder struct {
+	templateInterface emptyInterface
+	checkIsEmpty      checkIsEmpty
+}
+
+func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	templateInterface := encoder.templateInterface
+	templateInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
+	marshaler := (*realInterface).(json.Marshaler)
+	bytes, err := marshaler.MarshalJSON()
+	if err != nil {
+		stream.Error = err
+	} else {
+		stream.Write(bytes)
+	}
+}
+func (encoder *marshalerEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.checkIsEmpty.IsEmpty(ptr)
+}
+
+type textMarshalerEncoder struct {
+	templateInterface emptyInterface
+	checkIsEmpty      checkIsEmpty
+}
+
+func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	templateInterface := encoder.templateInterface
+	templateInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
+	marshaler := (*realInterface).(encoding.TextMarshaler)
+	bytes, err := marshaler.MarshalText()
+	if err != nil {
+		stream.Error = err
+	} else {
+		stream.WriteString(string(bytes))
+	}
+}
+
+func (encoder *textMarshalerEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.checkIsEmpty.IsEmpty(ptr)
+}
+
+type unmarshalerDecoder struct {
+	templateInterface emptyInterface
+}
+
+func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	templateInterface := decoder.templateInterface
+	templateInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
+	unmarshaler := (*realInterface).(json.Unmarshaler)
+	iter.nextToken()
+	iter.unreadByte() // skip spaces
+	bytes := iter.SkipAndReturnBytes()
+	err := unmarshaler.UnmarshalJSON(bytes)
+	if err != nil {
+		iter.ReportError("unmarshalerDecoder", err.Error())
+	}
+}
+
+type textUnmarshalerDecoder struct {
+	templateInterface emptyInterface
+}
+
+func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	templateInterface := decoder.templateInterface
+	templateInterface.word = ptr
+	realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
+	unmarshaler := (*realInterface).(encoding.TextUnmarshaler)
+	str := iter.ReadString()
+	err := unmarshaler.UnmarshalText([]byte(str))
+	if err != nil {
+		iter.ReportError("textUnmarshalerDecoder", err.Error())
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/feature_reflect_object.go
similarity index 50%
rename from vendor/github.com/json-iterator/go/reflect_struct_encoder.go
rename to vendor/github.com/json-iterator/go/feature_reflect_object.go
index d0759cf64..59b1235c0 100644
--- a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go
+++ b/vendor/github.com/json-iterator/go/feature_reflect_object.go
@@ -2,20 +2,23 @@ package jsoniter
 
 import (
 	"fmt"
-	"github.com/modern-go/reflect2"
 	"io"
 	"reflect"
+	"strings"
 	"unsafe"
 )
 
-func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
+func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
 	type bindingTo struct {
 		binding *Binding
 		toName  string
 		ignored bool
 	}
 	orderedBindings := []*bindingTo{}
-	structDescriptor := describeStruct(ctx, typ)
+	structDescriptor, err := describeStruct(cfg, typ)
+	if err != nil {
+		return nil, err
+	}
 	for _, binding := range structDescriptor.Fields {
 		for _, toName := range binding.ToNames {
 			new := &bindingTo{
@@ -26,13 +29,13 @@ func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
 				if old.toName != toName {
 					continue
 				}
-				old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding)
+				old.ignored, new.ignored = resolveConflictBinding(cfg, old.binding, new.binding)
 			}
 			orderedBindings = append(orderedBindings, new)
 		}
 	}
 	if len(orderedBindings) == 0 {
-		return &emptyStructEncoder{}
+		return &emptyStructEncoder{}, nil
 	}
 	finalOrderedFields := []structFieldTo{}
 	for _, bindingTo := range orderedBindings {
@@ -43,36 +46,12 @@ func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
 			})
 		}
 	}
-	return &structEncoder{typ, finalOrderedFields}
-}
-
-func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty {
-	encoder := createEncoderOfNative(ctx, typ)
-	if encoder != nil {
-		return encoder
-	}
-	kind := typ.Kind()
-	switch kind {
-	case reflect.Interface:
-		return &dynamicEncoder{typ}
-	case reflect.Struct:
-		return &structEncoder{typ: typ}
-	case reflect.Array:
-		return &arrayEncoder{}
-	case reflect.Slice:
-		return &sliceEncoder{}
-	case reflect.Map:
-		return encoderOfMap(ctx, typ)
-	case reflect.Ptr:
-		return &OptionalEncoder{}
-	default:
-		return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)}
-	}
+	return &structEncoder{structDescriptor.onePtrEmbedded, structDescriptor.onePtrOptimization, finalOrderedFields}, nil
 }
 
 func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
-	newTagged := new.Field.Tag().Get(cfg.getTagKey()) != ""
-	oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != ""
+	newTagged := new.Field.Tag.Get(cfg.getTagKey()) != ""
+	oldTagged := old.Field.Tag.Get(cfg.getTagKey()) != ""
 	if newTagged {
 		if oldTagged {
 			if len(old.levels) > len(new.levels) {
@@ -99,41 +78,62 @@ func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ig
 	}
 }
 
+func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
+	bindings := map[string]*Binding{}
+	structDescriptor, err := describeStruct(cfg, typ)
+	if err != nil {
+		return nil, err
+	}
+	for _, binding := range structDescriptor.Fields {
+		for _, fromName := range binding.FromNames {
+			old := bindings[fromName]
+			if old == nil {
+				bindings[fromName] = binding
+				continue
+			}
+			ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding)
+			if ignoreOld {
+				delete(bindings, fromName)
+			}
+			if !ignoreNew {
+				bindings[fromName] = binding
+			}
+		}
+	}
+	fields := map[string]*structFieldDecoder{}
+	for k, binding := range bindings {
+		fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
+	}
+	return createStructDecoder(typ, fields)
+}
+
 type structFieldEncoder struct {
-	field        reflect2.StructField
+	field        *reflect.StructField
 	fieldEncoder ValEncoder
 	omitempty    bool
 }
 
 func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	fieldPtr := encoder.field.UnsafeGet(ptr)
+	fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
 	encoder.fieldEncoder.Encode(fieldPtr, stream)
 	if stream.Error != nil && stream.Error != io.EOF {
-		stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error())
+		stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
 	}
 }
 
-func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	fieldPtr := encoder.field.UnsafeGet(ptr)
-	return encoder.fieldEncoder.IsEmpty(fieldPtr)
+func (encoder *structFieldEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
 }
 
-func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
-	isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil)
-	if !converted {
-		return false
-	}
-	fieldPtr := encoder.field.UnsafeGet(ptr)
-	return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
-}
-
-type IsEmbeddedPtrNil interface {
-	IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
+func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
+	return encoder.fieldEncoder.IsEmpty(fieldPtr)
 }
 
 type structEncoder struct {
-	typ    reflect2.Type
-	fields []structFieldTo
+	onePtrEmbedded     bool
+	onePtrOptimization bool
+	fields             []structFieldTo
 }
 
 type structFieldTo struct {
@@ -148,9 +148,6 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 		if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
 			continue
 		}
-		if field.encoder.IsEmbeddedPtrNil(ptr) {
-			continue
-		}
 		if isNotFirst {
 			stream.WriteMore()
 		}
@@ -159,8 +156,23 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 		isNotFirst = true
 	}
 	stream.WriteObjectEnd()
-	if stream.Error != nil && stream.Error != io.EOF {
-		stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
+}
+
+func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	e := (*emptyInterface)(unsafe.Pointer(&val))
+	if encoder.onePtrOptimization {
+		if e.word == nil && encoder.onePtrEmbedded {
+			stream.WriteObjectStart()
+			stream.WriteObjectEnd()
+			return
+		}
+		ptr := uintptr(e.word)
+		e.word = unsafe.Pointer(&ptr)
+	}
+	if reflect.TypeOf(val).Kind() == reflect.Ptr {
+		encoder.Encode(unsafe.Pointer(&e.word), stream)
+	} else {
+		encoder.Encode(e.word, stream)
 	}
 }
 
@@ -175,36 +187,10 @@ func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteEmptyObject()
 }
 
-func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return false
-}
-
-type stringModeNumberEncoder struct {
-	elemEncoder ValEncoder
-}
-
-func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.writeByte('"')
-	encoder.elemEncoder.Encode(ptr, stream)
-	stream.writeByte('"')
+func (encoder *emptyStructEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
 }
 
-func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.elemEncoder.IsEmpty(ptr)
-}
-
-type stringModeStringEncoder struct {
-	elemEncoder ValEncoder
-	cfg         *frozenConfig
-}
-
-func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	tempStream := encoder.cfg.BorrowStream(nil)
-	defer encoder.cfg.ReturnStream(tempStream)
-	encoder.elemEncoder.Encode(ptr, tempStream)
-	stream.WriteString(string(tempStream.Buffer()))
-}
-
-func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.elemEncoder.IsEmpty(ptr)
+func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
 }
diff --git a/vendor/github.com/json-iterator/go/feature_reflect_slice.go b/vendor/github.com/json-iterator/go/feature_reflect_slice.go
new file mode 100644
index 000000000..7377eec7b
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_reflect_slice.go
@@ -0,0 +1,149 @@
+package jsoniter
+
+import (
+	"fmt"
+	"io"
+	"reflect"
+	"unsafe"
+)
+
+func decoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
+	decoder, err := decoderOfType(cfg, typ.Elem())
+	if err != nil {
+		return nil, err
+	}
+	return &sliceDecoder{typ, typ.Elem(), decoder}, nil
+}
+
+func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
+	encoder, err := encoderOfType(cfg, typ.Elem())
+	if err != nil {
+		return nil, err
+	}
+	if typ.Elem().Kind() == reflect.Map {
+		encoder = &optionalEncoder{encoder}
+	}
+	return &sliceEncoder{typ, typ.Elem(), encoder}, nil
+}
+
+type sliceEncoder struct {
+	sliceType   reflect.Type
+	elemType    reflect.Type
+	elemEncoder ValEncoder
+}
+
+func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	slice := (*sliceHeader)(ptr)
+	if slice.Data == nil {
+		stream.WriteNil()
+		return
+	}
+	if slice.Len == 0 {
+		stream.WriteEmptyArray()
+		return
+	}
+	stream.WriteArrayStart()
+	elemPtr := unsafe.Pointer(slice.Data)
+	encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
+	for i := 1; i < slice.Len; i++ {
+		stream.WriteMore()
+		elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
+		encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
+	}
+	stream.WriteArrayEnd()
+	if stream.Error != nil && stream.Error != io.EOF {
+		stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
+	}
+}
+
+func (encoder *sliceEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	slice := (*sliceHeader)(ptr)
+	return slice.Len == 0
+}
+
+type sliceDecoder struct {
+	sliceType   reflect.Type
+	elemType    reflect.Type
+	elemDecoder ValDecoder
+}
+
+// sliceHeader is a safe version of SliceHeader used within this package.
+type sliceHeader struct {
+	Data unsafe.Pointer
+	Len  int
+	Cap  int
+}
+
+func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.doDecode(ptr, iter)
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
+	}
+}
+
+func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
+	slice := (*sliceHeader)(ptr)
+	if iter.ReadNil() {
+		slice.Len = 0
+		slice.Cap = 0
+		slice.Data = nil
+		return
+	}
+	reuseSlice(slice, decoder.sliceType, 4)
+	slice.Len = 0
+	offset := uintptr(0)
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		growOne(slice, decoder.sliceType, decoder.elemType)
+		decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
+		offset += decoder.elemType.Size()
+		return true
+	})
+}
+
+// grow grows the slice s so that it can hold extra more values, allocating
+// more capacity if needed. It also returns the old and new slice lengths.
+func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Type) {
+	newLen := slice.Len + 1
+	if newLen <= slice.Cap {
+		slice.Len = newLen
+		return
+	}
+	newCap := slice.Cap
+	if newCap == 0 {
+		newCap = 1
+	} else {
+		for newCap < newLen {
+			if slice.Len < 1024 {
+				newCap += newCap
+			} else {
+				newCap += newCap / 4
+			}
+		}
+	}
+	newVal := reflect.MakeSlice(sliceType, newLen, newCap)
+	dst := unsafe.Pointer(newVal.Pointer())
+	// copy old array into new array
+	originalBytesCount := uintptr(slice.Len) * elementType.Size()
+	srcPtr := (*[1 << 30]byte)(slice.Data)
+	dstPtr := (*[1 << 30]byte)(dst)
+	for i := uintptr(0); i < originalBytesCount; i++ {
+		dstPtr[i] = srcPtr[i]
+	}
+	slice.Data = dst
+	slice.Len = newLen
+	slice.Cap = newCap
+}
+
+func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) {
+	if expectedCap <= slice.Cap {
+		return
+	}
+	newVal := reflect.MakeSlice(sliceType, 0, expectedCap)
+	dst := unsafe.Pointer(newVal.Pointer())
+	slice.Data = dst
+	slice.Cap = expectedCap
+}
diff --git a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go
similarity index 65%
rename from vendor/github.com/json-iterator/go/reflect_struct_decoder.go
rename to vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go
index 355d2d116..b3417fd73 100644
--- a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go
+++ b/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go
@@ -3,78 +3,38 @@ package jsoniter
 import (
 	"fmt"
 	"io"
+	"reflect"
 	"strings"
 	"unsafe"
-
-	"github.com/modern-go/reflect2"
 )
 
-func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
-	bindings := map[string]*Binding{}
-	structDescriptor := describeStruct(ctx, typ)
-	for _, binding := range structDescriptor.Fields {
-		for _, fromName := range binding.FromNames {
-			old := bindings[fromName]
-			if old == nil {
-				bindings[fromName] = binding
-				continue
-			}
-			ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding)
-			if ignoreOld {
-				delete(bindings, fromName)
-			}
-			if !ignoreNew {
-				bindings[fromName] = binding
-			}
-		}
-	}
-	fields := map[string]*structFieldDecoder{}
-	for k, binding := range bindings {
-		fields[k] = binding.Decoder.(*structFieldDecoder)
-	}
-
-	if !ctx.caseSensitive() {
-		for k, binding := range bindings {
-			if _, found := fields[strings.ToLower(k)]; !found {
-				fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
-			}
-		}
-	}
-
-	return createStructDecoder(ctx, typ, fields)
-}
-
-func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder {
-	if ctx.disallowUnknownFields {
-		return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
-	}
-	knownHash := map[int64]struct{}{
+func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) {
+	knownHash := map[int32]struct{}{
 		0: {},
 	}
-
 	switch len(fields) {
 	case 0:
-		return &skipObjectDecoder{typ}
+		return &skipObjectDecoder{typ}, nil
 	case 1:
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
-			return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}
+			return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}, nil
 		}
 	case 2:
-		var fieldHash1 int64
-		var fieldHash2 int64
+		var fieldHash1 int32
+		var fieldHash2 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldHash1 == 0 {
@@ -85,19 +45,19 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 				fieldDecoder2 = fieldDecoder
 			}
 		}
-		return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}
+		return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}, nil
 	case 3:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -112,23 +72,21 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &threeFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
 	case 4:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
-		var fieldName4 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
+		var fieldName4 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
 		var fieldDecoder4 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -146,26 +104,24 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &fourFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4}, nil
 	case 5:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
-		var fieldName4 int64
-		var fieldName5 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
+		var fieldName4 int32
+		var fieldName5 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
 		var fieldDecoder4 *structFieldDecoder
 		var fieldDecoder5 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -186,18 +142,15 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &fiveFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4,
-			fieldName5, fieldDecoder5}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil
 	case 6:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
-		var fieldName4 int64
-		var fieldName5 int64
-		var fieldName6 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
+		var fieldName4 int32
+		var fieldName5 int32
+		var fieldName6 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
@@ -205,10 +158,10 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 		var fieldDecoder5 *structFieldDecoder
 		var fieldDecoder6 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -232,20 +185,16 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &sixFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4,
-			fieldName5, fieldDecoder5,
-			fieldName6, fieldDecoder6}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil
 	case 7:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
-		var fieldName4 int64
-		var fieldName5 int64
-		var fieldName6 int64
-		var fieldName7 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
+		var fieldName4 int32
+		var fieldName5 int32
+		var fieldName6 int32
+		var fieldName7 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
@@ -254,10 +203,10 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 		var fieldDecoder6 *structFieldDecoder
 		var fieldDecoder7 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -284,22 +233,18 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &sevenFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4,
-			fieldName5, fieldDecoder5,
-			fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7}, nil
 	case 8:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
-		var fieldName4 int64
-		var fieldName5 int64
-		var fieldName6 int64
-		var fieldName7 int64
-		var fieldName8 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
+		var fieldName4 int32
+		var fieldName5 int32
+		var fieldName6 int32
+		var fieldName7 int32
+		var fieldName8 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
@@ -309,10 +254,10 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 		var fieldDecoder7 *structFieldDecoder
 		var fieldDecoder8 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -342,24 +287,19 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &eightFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4,
-			fieldName5, fieldDecoder5,
-			fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7,
-			fieldName8, fieldDecoder8}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil
 	case 9:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
-		var fieldName4 int64
-		var fieldName5 int64
-		var fieldName6 int64
-		var fieldName7 int64
-		var fieldName8 int64
-		var fieldName9 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
+		var fieldName4 int32
+		var fieldName5 int32
+		var fieldName6 int32
+		var fieldName7 int32
+		var fieldName8 int32
+		var fieldName9 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
@@ -370,10 +310,10 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 		var fieldDecoder8 *structFieldDecoder
 		var fieldDecoder9 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -406,26 +346,20 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &nineFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4,
-			fieldName5, fieldDecoder5,
-			fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7,
-			fieldName8, fieldDecoder8,
-			fieldName9, fieldDecoder9}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil
 	case 10:
-		var fieldName1 int64
-		var fieldName2 int64
-		var fieldName3 int64
-		var fieldName4 int64
-		var fieldName5 int64
-		var fieldName6 int64
-		var fieldName7 int64
-		var fieldName8 int64
-		var fieldName9 int64
-		var fieldName10 int64
+		var fieldName1 int32
+		var fieldName2 int32
+		var fieldName3 int32
+		var fieldName4 int32
+		var fieldName5 int32
+		var fieldName6 int32
+		var fieldName7 int32
+		var fieldName8 int32
+		var fieldName9 int32
+		var fieldName10 int32
 		var fieldDecoder1 *structFieldDecoder
 		var fieldDecoder2 *structFieldDecoder
 		var fieldDecoder3 *structFieldDecoder
@@ -437,10 +371,10 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 		var fieldDecoder9 *structFieldDecoder
 		var fieldDecoder10 *structFieldDecoder
 		for fieldName, fieldDecoder := range fields {
-			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			fieldHash := calcHash(fieldName)
 			_, known := knownHash[fieldHash]
 			if known {
-				return &generalStructDecoder{typ, fields, false}
+				return &generalStructDecoder{typ, fields}, nil
 			}
 			knownHash[fieldHash] = struct{}{}
 			if fieldName1 == 0 {
@@ -476,80 +410,48 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
 			}
 		}
 		return &tenFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1,
-			fieldName2, fieldDecoder2,
-			fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4,
-			fieldName5, fieldDecoder5,
-			fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7,
-			fieldName8, fieldDecoder8,
-			fieldName9, fieldDecoder9,
-			fieldName10, fieldDecoder10}
+			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9,
+			fieldName10, fieldDecoder10}, nil
 	}
-	return &generalStructDecoder{typ, fields, false}
+	return &generalStructDecoder{typ, fields}, nil
 }
 
 type generalStructDecoder struct {
-	typ                   reflect2.Type
-	fields                map[string]*structFieldDecoder
-	disallowUnknownFields bool
+	typ    reflect.Type
+	fields map[string]*structFieldDecoder
 }
 
 func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
-	var c byte
-	for c = ','; c == ','; c = iter.nextToken() {
-		decoder.decodeOneField(ptr, iter)
-	}
-	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
-	}
-	if c != '}' {
-		iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c}))
-	}
-}
-
-func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) {
-	var field string
-	var fieldDecoder *structFieldDecoder
-	if iter.cfg.objectFieldMustBeSimpleString {
-		fieldBytes := iter.ReadStringAsSlice()
-		field = *(*string)(unsafe.Pointer(&fieldBytes))
-		fieldDecoder = decoder.fields[field]
-		if fieldDecoder == nil && !iter.cfg.caseSensitive {
-			fieldDecoder = decoder.fields[strings.ToLower(field)]
-		}
+	fieldBytes := iter.readObjectFieldAsBytes()
+	field := *(*string)(unsafe.Pointer(&fieldBytes))
+	fieldDecoder := decoder.fields[strings.ToLower(field)]
+	if fieldDecoder == nil {
+		iter.Skip()
 	} else {
-		field = iter.ReadString()
-		fieldDecoder = decoder.fields[field]
-		if fieldDecoder == nil && !iter.cfg.caseSensitive {
-			fieldDecoder = decoder.fields[strings.ToLower(field)]
-		}
+		fieldDecoder.Decode(ptr, iter)
 	}
-	if fieldDecoder == nil {
-		msg := "found unknown field: " + field
-		if decoder.disallowUnknownFields {
-			iter.ReportError("ReadObject", msg)
-		}
-		c := iter.nextToken()
-		if c != ':' {
-			iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+	for iter.nextToken() == ',' {
+		fieldBytes = iter.readObjectFieldAsBytes()
+		field = *(*string)(unsafe.Pointer(&fieldBytes))
+		fieldDecoder = decoder.fields[strings.ToLower(field)]
+		if fieldDecoder == nil {
+			iter.Skip()
+		} else {
+			fieldDecoder.Decode(ptr, iter)
 		}
-		iter.Skip()
-		return
 	}
-	c := iter.nextToken()
-	if c != ':' {
-		iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
-	fieldDecoder.Decode(ptr, iter)
 }
 
 type skipObjectDecoder struct {
-	typ reflect2.Type
+	typ reflect.Type
 }
 
 func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
@@ -562,8 +464,8 @@ func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 }
 
 type oneFieldStructDecoder struct {
-	typ          reflect2.Type
-	fieldHash    int64
+	typ          reflect.Type
+	fieldHash    int32
 	fieldDecoder *structFieldDecoder
 }
 
@@ -582,15 +484,15 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type twoFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
 }
 
@@ -612,17 +514,17 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type threeFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
-	fieldHash3    int64
+	fieldHash3    int32
 	fieldDecoder3 *structFieldDecoder
 }
 
@@ -646,19 +548,19 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type fourFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
-	fieldHash3    int64
+	fieldHash3    int32
 	fieldDecoder3 *structFieldDecoder
-	fieldHash4    int64
+	fieldHash4    int32
 	fieldDecoder4 *structFieldDecoder
 }
 
@@ -684,21 +586,21 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type fiveFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
-	fieldHash3    int64
+	fieldHash3    int32
 	fieldDecoder3 *structFieldDecoder
-	fieldHash4    int64
+	fieldHash4    int32
 	fieldDecoder4 *structFieldDecoder
-	fieldHash5    int64
+	fieldHash5    int32
 	fieldDecoder5 *structFieldDecoder
 }
 
@@ -726,23 +628,23 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type sixFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
-	fieldHash3    int64
+	fieldHash3    int32
 	fieldDecoder3 *structFieldDecoder
-	fieldHash4    int64
+	fieldHash4    int32
 	fieldDecoder4 *structFieldDecoder
-	fieldHash5    int64
+	fieldHash5    int32
 	fieldDecoder5 *structFieldDecoder
-	fieldHash6    int64
+	fieldHash6    int32
 	fieldDecoder6 *structFieldDecoder
 }
 
@@ -772,25 +674,25 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type sevenFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
-	fieldHash3    int64
+	fieldHash3    int32
 	fieldDecoder3 *structFieldDecoder
-	fieldHash4    int64
+	fieldHash4    int32
 	fieldDecoder4 *structFieldDecoder
-	fieldHash5    int64
+	fieldHash5    int32
 	fieldDecoder5 *structFieldDecoder
-	fieldHash6    int64
+	fieldHash6    int32
 	fieldDecoder6 *structFieldDecoder
-	fieldHash7    int64
+	fieldHash7    int32
 	fieldDecoder7 *structFieldDecoder
 }
 
@@ -822,27 +724,27 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type eightFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
-	fieldHash3    int64
+	fieldHash3    int32
 	fieldDecoder3 *structFieldDecoder
-	fieldHash4    int64
+	fieldHash4    int32
 	fieldDecoder4 *structFieldDecoder
-	fieldHash5    int64
+	fieldHash5    int32
 	fieldDecoder5 *structFieldDecoder
-	fieldHash6    int64
+	fieldHash6    int32
 	fieldDecoder6 *structFieldDecoder
-	fieldHash7    int64
+	fieldHash7    int32
 	fieldDecoder7 *structFieldDecoder
-	fieldHash8    int64
+	fieldHash8    int32
 	fieldDecoder8 *structFieldDecoder
 }
 
@@ -876,29 +778,29 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type nineFieldsStructDecoder struct {
-	typ           reflect2.Type
-	fieldHash1    int64
+	typ           reflect.Type
+	fieldHash1    int32
 	fieldDecoder1 *structFieldDecoder
-	fieldHash2    int64
+	fieldHash2    int32
 	fieldDecoder2 *structFieldDecoder
-	fieldHash3    int64
+	fieldHash3    int32
 	fieldDecoder3 *structFieldDecoder
-	fieldHash4    int64
+	fieldHash4    int32
 	fieldDecoder4 *structFieldDecoder
-	fieldHash5    int64
+	fieldHash5    int32
 	fieldDecoder5 *structFieldDecoder
-	fieldHash6    int64
+	fieldHash6    int32
 	fieldDecoder6 *structFieldDecoder
-	fieldHash7    int64
+	fieldHash7    int32
 	fieldDecoder7 *structFieldDecoder
-	fieldHash8    int64
+	fieldHash8    int32
 	fieldDecoder8 *structFieldDecoder
-	fieldHash9    int64
+	fieldHash9    int32
 	fieldDecoder9 *structFieldDecoder
 }
 
@@ -934,31 +836,31 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type tenFieldsStructDecoder struct {
-	typ            reflect2.Type
-	fieldHash1     int64
+	typ            reflect.Type
+	fieldHash1     int32
 	fieldDecoder1  *structFieldDecoder
-	fieldHash2     int64
+	fieldHash2     int32
 	fieldDecoder2  *structFieldDecoder
-	fieldHash3     int64
+	fieldHash3     int32
 	fieldDecoder3  *structFieldDecoder
-	fieldHash4     int64
+	fieldHash4     int32
 	fieldDecoder4  *structFieldDecoder
-	fieldHash5     int64
+	fieldHash5     int32
 	fieldDecoder5  *structFieldDecoder
-	fieldHash6     int64
+	fieldHash6     int32
 	fieldDecoder6  *structFieldDecoder
-	fieldHash7     int64
+	fieldHash7     int32
 	fieldDecoder7  *structFieldDecoder
-	fieldHash8     int64
+	fieldHash8     int32
 	fieldDecoder8  *structFieldDecoder
-	fieldHash9     int64
+	fieldHash9     int32
 	fieldDecoder9  *structFieldDecoder
-	fieldHash10    int64
+	fieldHash10    int32
 	fieldDecoder10 *structFieldDecoder
 }
 
@@ -996,53 +898,19 @@ func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
 	}
 }
 
 type structFieldDecoder struct {
-	field        reflect2.StructField
+	field        *reflect.StructField
 	fieldDecoder ValDecoder
 }
 
 func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	fieldPtr := decoder.field.UnsafeGet(ptr)
+	fieldPtr := unsafe.Pointer(uintptr(ptr) + decoder.field.Offset)
 	decoder.fieldDecoder.Decode(fieldPtr, iter)
 	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error())
-	}
-}
-
-type stringModeStringDecoder struct {
-	elemDecoder ValDecoder
-	cfg         *frozenConfig
-}
-
-func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	decoder.elemDecoder.Decode(ptr, iter)
-	str := *((*string)(ptr))
-	tempIter := decoder.cfg.BorrowIterator([]byte(str))
-	defer decoder.cfg.ReturnIterator(tempIter)
-	*((*string)(ptr)) = tempIter.ReadString()
-}
-
-type stringModeNumberDecoder struct {
-	elemDecoder ValDecoder
-}
-
-func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	c := iter.nextToken()
-	if c != '"' {
-		iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
-		return
-	}
-	decoder.elemDecoder.Decode(ptr, iter)
-	if iter.Error != nil {
-		return
-	}
-	c = iter.readByte()
-	if c != '"' {
-		iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
-		return
+		iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
 	}
 }
diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/feature_stream.go
similarity index 60%
rename from vendor/github.com/json-iterator/go/stream.go
rename to vendor/github.com/json-iterator/go/feature_stream.go
index 17662fded..9c8470a03 100644
--- a/vendor/github.com/json-iterator/go/stream.go
+++ b/vendor/github.com/json-iterator/go/feature_stream.go
@@ -4,15 +4,15 @@ import (
 	"io"
 )
 
-// stream is a io.Writer like object, with JSON specific write functions.
+// Stream is a io.Writer like object, with JSON specific write functions.
 // Error is not returned as return value, but stored as Error member on this stream instance.
 type Stream struct {
-	cfg        *frozenConfig
-	out        io.Writer
-	buf        []byte
-	Error      error
-	indention  int
-	Attachment interface{} // open for customized encoder
+	cfg       *frozenConfig
+	out       io.Writer
+	buf       []byte
+	n         int
+	Error     error
+	indention int
 }
 
 // NewStream create new stream instance.
@@ -23,7 +23,8 @@ func NewStream(cfg API, out io.Writer, bufSize int) *Stream {
 	return &Stream{
 		cfg:       cfg.(*frozenConfig),
 		out:       out,
-		buf:       make([]byte, 0, bufSize),
+		buf:       make([]byte, bufSize),
+		n:         0,
 		Error:     nil,
 		indention: 0,
 	}
@@ -37,27 +38,22 @@ func (stream *Stream) Pool() StreamPool {
 // Reset reuse this stream instance by assign a new writer
 func (stream *Stream) Reset(out io.Writer) {
 	stream.out = out
-	stream.buf = stream.buf[:0]
+	stream.n = 0
 }
 
 // Available returns how many bytes are unused in the buffer.
 func (stream *Stream) Available() int {
-	return cap(stream.buf) - len(stream.buf)
+	return len(stream.buf) - stream.n
 }
 
 // Buffered returns the number of bytes that have been written into the current buffer.
 func (stream *Stream) Buffered() int {
-	return len(stream.buf)
+	return stream.n
 }
 
 // Buffer if writer is nil, use this method to take the result
 func (stream *Stream) Buffer() []byte {
-	return stream.buf
-}
-
-// SetBuffer allows to append to the internal buffer directly
-func (stream *Stream) SetBuffer(buf []byte) {
-	stream.buf = buf
+	return stream.buf[:stream.n]
 }
 
 // Write writes the contents of p into the buffer.
@@ -65,34 +61,97 @@ func (stream *Stream) SetBuffer(buf []byte) {
 // If nn < len(p), it also returns an error explaining
 // why the write is short.
 func (stream *Stream) Write(p []byte) (nn int, err error) {
-	stream.buf = append(stream.buf, p...)
-	if stream.out != nil {
-		nn, err = stream.out.Write(stream.buf)
-		stream.buf = stream.buf[nn:]
-		return
+	for len(p) > stream.Available() && stream.Error == nil {
+		if stream.out == nil {
+			stream.growAtLeast(len(p))
+		} else {
+			var n int
+			if stream.Buffered() == 0 {
+				// Large write, empty buffer.
+				// Write directly from p to avoid copy.
+				n, stream.Error = stream.out.Write(p)
+			} else {
+				n = copy(stream.buf[stream.n:], p)
+				stream.n += n
+				stream.Flush()
+			}
+			nn += n
+			p = p[n:]
+		}
 	}
-	return len(p), nil
+	if stream.Error != nil {
+		return nn, stream.Error
+	}
+	n := copy(stream.buf[stream.n:], p)
+	stream.n += n
+	nn += n
+	return nn, nil
 }
 
 // WriteByte writes a single byte.
 func (stream *Stream) writeByte(c byte) {
-	stream.buf = append(stream.buf, c)
+	if stream.Error != nil {
+		return
+	}
+	if stream.Available() < 1 {
+		stream.growAtLeast(1)
+	}
+	stream.buf[stream.n] = c
+	stream.n++
 }
 
 func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
-	stream.buf = append(stream.buf, c1, c2)
+	if stream.Error != nil {
+		return
+	}
+	if stream.Available() < 2 {
+		stream.growAtLeast(2)
+	}
+	stream.buf[stream.n] = c1
+	stream.buf[stream.n+1] = c2
+	stream.n += 2
 }
 
 func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
-	stream.buf = append(stream.buf, c1, c2, c3)
+	if stream.Error != nil {
+		return
+	}
+	if stream.Available() < 3 {
+		stream.growAtLeast(3)
+	}
+	stream.buf[stream.n] = c1
+	stream.buf[stream.n+1] = c2
+	stream.buf[stream.n+2] = c3
+	stream.n += 3
 }
 
 func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
-	stream.buf = append(stream.buf, c1, c2, c3, c4)
+	if stream.Error != nil {
+		return
+	}
+	if stream.Available() < 4 {
+		stream.growAtLeast(4)
+	}
+	stream.buf[stream.n] = c1
+	stream.buf[stream.n+1] = c2
+	stream.buf[stream.n+2] = c3
+	stream.buf[stream.n+3] = c4
+	stream.n += 4
 }
 
 func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
-	stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
+	if stream.Error != nil {
+		return
+	}
+	if stream.Available() < 5 {
+		stream.growAtLeast(5)
+	}
+	stream.buf[stream.n] = c1
+	stream.buf[stream.n+1] = c2
+	stream.buf[stream.n+2] = c3
+	stream.buf[stream.n+3] = c4
+	stream.buf[stream.n+4] = c5
+	stream.n += 5
 }
 
 // Flush writes any buffered data to the underlying io.Writer.
@@ -103,20 +162,53 @@ func (stream *Stream) Flush() error {
 	if stream.Error != nil {
 		return stream.Error
 	}
-	n, err := stream.out.Write(stream.buf)
+	if stream.n == 0 {
+		return nil
+	}
+	n, err := stream.out.Write(stream.buf[0:stream.n])
+	if n < stream.n && err == nil {
+		err = io.ErrShortWrite
+	}
 	if err != nil {
-		if stream.Error == nil {
-			stream.Error = err
+		if n > 0 && n < stream.n {
+			copy(stream.buf[0:stream.n-n], stream.buf[n:stream.n])
 		}
+		stream.n -= n
+		stream.Error = err
 		return err
 	}
-	stream.buf = stream.buf[n:]
+	stream.n = 0
 	return nil
 }
 
+func (stream *Stream) ensure(minimal int) {
+	available := stream.Available()
+	if available < minimal {
+		stream.growAtLeast(minimal)
+	}
+}
+
+func (stream *Stream) growAtLeast(minimal int) {
+	if stream.out != nil {
+		stream.Flush()
+	}
+	toGrow := len(stream.buf)
+	if toGrow < minimal {
+		toGrow = minimal
+	}
+	newBuf := make([]byte, len(stream.buf)+toGrow)
+	copy(newBuf, stream.Buffer())
+	stream.buf = newBuf
+}
+
 // WriteRaw write string out without quotes, just like []byte
 func (stream *Stream) WriteRaw(s string) {
-	stream.buf = append(stream.buf, s...)
+	stream.ensure(len(s))
+	if stream.Error != nil {
+		return
+	}
+	n := copy(stream.buf[stream.n:], s)
+	stream.n += n
 }
 
 // WriteNil write null to stream
@@ -177,7 +269,6 @@ func (stream *Stream) WriteEmptyObject() {
 func (stream *Stream) WriteMore() {
 	stream.writeByte(',')
 	stream.writeIndention(0)
-	stream.Flush()
 }
 
 // WriteArrayStart write [ with possible indention
@@ -189,7 +280,8 @@ func (stream *Stream) WriteArrayStart() {
 
 // WriteEmptyArray write []
 func (stream *Stream) WriteEmptyArray() {
-	stream.writeTwoBytes('[', ']')
+	stream.writeByte('[')
+	stream.writeByte(']')
 }
 
 // WriteArrayEnd write ] with possible indention
@@ -205,7 +297,9 @@ func (stream *Stream) writeIndention(delta int) {
 	}
 	stream.writeByte('\n')
 	toWrite := stream.indention - delta
-	for i := 0; i < toWrite; i++ {
-		stream.buf = append(stream.buf, ' ')
+	stream.ensure(toWrite)
+	for i := 0; i < toWrite && stream.n < len(stream.buf); i++ {
+		stream.buf[stream.n] = ' '
+		stream.n++
 	}
 }
diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/feature_stream_float.go
similarity index 85%
rename from vendor/github.com/json-iterator/go/stream_float.go
rename to vendor/github.com/json-iterator/go/feature_stream_float.go
index f318d2c59..9a404e11d 100644
--- a/vendor/github.com/json-iterator/go/stream_float.go
+++ b/vendor/github.com/json-iterator/go/feature_stream_float.go
@@ -21,7 +21,7 @@ func (stream *Stream) WriteFloat32(val float32) {
 			fmt = 'e'
 		}
 	}
-	stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32)
+	stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 32))
 }
 
 // WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster
@@ -43,12 +43,13 @@ func (stream *Stream) WriteFloat32Lossy(val float32) {
 		return
 	}
 	stream.writeByte('.')
+	stream.ensure(10)
 	for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
 		stream.writeByte('0')
 	}
 	stream.WriteUint64(fval)
-	for stream.buf[len(stream.buf)-1] == '0' {
-		stream.buf = stream.buf[:len(stream.buf)-1]
+	for stream.buf[stream.n-1] == '0' {
+		stream.n--
 	}
 }
 
@@ -62,7 +63,7 @@ func (stream *Stream) WriteFloat64(val float64) {
 			fmt = 'e'
 		}
 	}
-	stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64)
+	stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 64))
 }
 
 // WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster
@@ -84,11 +85,12 @@ func (stream *Stream) WriteFloat64Lossy(val float64) {
 		return
 	}
 	stream.writeByte('.')
+	stream.ensure(10)
 	for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
 		stream.writeByte('0')
 	}
 	stream.WriteUint64(fval)
-	for stream.buf[len(stream.buf)-1] == '0' {
-		stream.buf = stream.buf[:len(stream.buf)-1]
+	for stream.buf[stream.n-1] == '0' {
+		stream.n--
 	}
 }
diff --git a/vendor/github.com/json-iterator/go/feature_stream_int.go b/vendor/github.com/json-iterator/go/feature_stream_int.go
new file mode 100644
index 000000000..7cfd522c1
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/feature_stream_int.go
@@ -0,0 +1,320 @@
+package jsoniter
+
+var digits []uint32
+
+func init() {
+	digits = make([]uint32, 1000)
+	for i := uint32(0); i < 1000; i++ {
+		digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
+		if i < 10 {
+			digits[i] += 2 << 24
+		} else if i < 100 {
+			digits[i] += 1 << 24
+		}
+	}
+}
+
+func writeFirstBuf(buf []byte, v uint32, n int) int {
+	start := v >> 24
+	if start == 0 {
+		buf[n] = byte(v >> 16)
+		n++
+		buf[n] = byte(v >> 8)
+		n++
+	} else if start == 1 {
+		buf[n] = byte(v >> 8)
+		n++
+	}
+	buf[n] = byte(v)
+	n++
+	return n
+}
+
+func writeBuf(buf []byte, v uint32, n int) {
+	buf[n] = byte(v >> 16)
+	buf[n+1] = byte(v >> 8)
+	buf[n+2] = byte(v)
+}
+
+// WriteUint8 write uint8 to stream
+func (stream *Stream) WriteUint8(val uint8) {
+	stream.ensure(3)
+	stream.n = writeFirstBuf(stream.buf, digits[val], stream.n)
+}
+
+// WriteInt8 write int8 to stream
+func (stream *Stream) WriteInt8(nval int8) {
+	stream.ensure(4)
+	n := stream.n
+	var val uint8
+	if nval < 0 {
+		val = uint8(-nval)
+		stream.buf[n] = '-'
+		n++
+	} else {
+		val = uint8(nval)
+	}
+	stream.n = writeFirstBuf(stream.buf, digits[val], n)
+}
+
+// WriteUint16 write uint16 to stream
+func (stream *Stream) WriteUint16(val uint16) {
+	stream.ensure(5)
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.n = writeFirstBuf(stream.buf, digits[val], stream.n)
+		return
+	}
+	r1 := val - q1*1000
+	n := writeFirstBuf(stream.buf, digits[q1], stream.n)
+	writeBuf(stream.buf, digits[r1], n)
+	stream.n = n + 3
+	return
+}
+
+// WriteInt16 write int16 to stream
+func (stream *Stream) WriteInt16(nval int16) {
+	stream.ensure(6)
+	n := stream.n
+	var val uint16
+	if nval < 0 {
+		val = uint16(-nval)
+		stream.buf[n] = '-'
+		n++
+	} else {
+		val = uint16(nval)
+	}
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.n = writeFirstBuf(stream.buf, digits[val], n)
+		return
+	}
+	r1 := val - q1*1000
+	n = writeFirstBuf(stream.buf, digits[q1], n)
+	writeBuf(stream.buf, digits[r1], n)
+	stream.n = n + 3
+	return
+}
+
+// WriteUint32 write uint32 to stream
+func (stream *Stream) WriteUint32(val uint32) {
+	stream.ensure(10)
+	n := stream.n
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.n = writeFirstBuf(stream.buf, digits[val], n)
+		return
+	}
+	r1 := val - q1*1000
+	q2 := q1 / 1000
+	if q2 == 0 {
+		n := writeFirstBuf(stream.buf, digits[q1], n)
+		writeBuf(stream.buf, digits[r1], n)
+		stream.n = n + 3
+		return
+	}
+	r2 := q1 - q2*1000
+	q3 := q2 / 1000
+	if q3 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q2], n)
+	} else {
+		r3 := q2 - q3*1000
+		stream.buf[n] = byte(q3 + '0')
+		n++
+		writeBuf(stream.buf, digits[r3], n)
+		n += 3
+	}
+	writeBuf(stream.buf, digits[r2], n)
+	writeBuf(stream.buf, digits[r1], n+3)
+	stream.n = n + 6
+}
+
+// WriteInt32 write int32 to stream
+func (stream *Stream) WriteInt32(nval int32) {
+	stream.ensure(11)
+	n := stream.n
+	var val uint32
+	if nval < 0 {
+		val = uint32(-nval)
+		stream.buf[n] = '-'
+		n++
+	} else {
+		val = uint32(nval)
+	}
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.n = writeFirstBuf(stream.buf, digits[val], n)
+		return
+	}
+	r1 := val - q1*1000
+	q2 := q1 / 1000
+	if q2 == 0 {
+		n := writeFirstBuf(stream.buf, digits[q1], n)
+		writeBuf(stream.buf, digits[r1], n)
+		stream.n = n + 3
+		return
+	}
+	r2 := q1 - q2*1000
+	q3 := q2 / 1000
+	if q3 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q2], n)
+	} else {
+		r3 := q2 - q3*1000
+		stream.buf[n] = byte(q3 + '0')
+		n++
+		writeBuf(stream.buf, digits[r3], n)
+		n += 3
+	}
+	writeBuf(stream.buf, digits[r2], n)
+	writeBuf(stream.buf, digits[r1], n+3)
+	stream.n = n + 6
+}
+
+// WriteUint64 write uint64 to stream
+func (stream *Stream) WriteUint64(val uint64) {
+	stream.ensure(20)
+	n := stream.n
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.n = writeFirstBuf(stream.buf, digits[val], n)
+		return
+	}
+	r1 := val - q1*1000
+	q2 := q1 / 1000
+	if q2 == 0 {
+		n := writeFirstBuf(stream.buf, digits[q1], n)
+		writeBuf(stream.buf, digits[r1], n)
+		stream.n = n + 3
+		return
+	}
+	r2 := q1 - q2*1000
+	q3 := q2 / 1000
+	if q3 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q2], n)
+		writeBuf(stream.buf, digits[r2], n)
+		writeBuf(stream.buf, digits[r1], n+3)
+		stream.n = n + 6
+		return
+	}
+	r3 := q2 - q3*1000
+	q4 := q3 / 1000
+	if q4 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q3], n)
+		writeBuf(stream.buf, digits[r3], n)
+		writeBuf(stream.buf, digits[r2], n+3)
+		writeBuf(stream.buf, digits[r1], n+6)
+		stream.n = n + 9
+		return
+	}
+	r4 := q3 - q4*1000
+	q5 := q4 / 1000
+	if q5 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q4], n)
+		writeBuf(stream.buf, digits[r4], n)
+		writeBuf(stream.buf, digits[r3], n+3)
+		writeBuf(stream.buf, digits[r2], n+6)
+		writeBuf(stream.buf, digits[r1], n+9)
+		stream.n = n + 12
+		return
+	}
+	r5 := q4 - q5*1000
+	q6 := q5 / 1000
+	if q6 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q5], n)
+	} else {
+		n = writeFirstBuf(stream.buf, digits[q6], n)
+		r6 := q5 - q6*1000
+		writeBuf(stream.buf, digits[r6], n)
+		n += 3
+	}
+	writeBuf(stream.buf, digits[r5], n)
+	writeBuf(stream.buf, digits[r4], n+3)
+	writeBuf(stream.buf, digits[r3], n+6)
+	writeBuf(stream.buf, digits[r2], n+9)
+	writeBuf(stream.buf, digits[r1], n+12)
+	stream.n = n + 15
+}
+
+// WriteInt64 write int64 to stream
+func (stream *Stream) WriteInt64(nval int64) {
+	stream.ensure(20)
+	n := stream.n
+	var val uint64
+	if nval < 0 {
+		val = uint64(-nval)
+		stream.buf[n] = '-'
+		n++
+	} else {
+		val = uint64(nval)
+	}
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.n = writeFirstBuf(stream.buf, digits[val], n)
+		return
+	}
+	r1 := val - q1*1000
+	q2 := q1 / 1000
+	if q2 == 0 {
+		n := writeFirstBuf(stream.buf, digits[q1], n)
+		writeBuf(stream.buf, digits[r1], n)
+		stream.n = n + 3
+		return
+	}
+	r2 := q1 - q2*1000
+	q3 := q2 / 1000
+	if q3 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q2], n)
+		writeBuf(stream.buf, digits[r2], n)
+		writeBuf(stream.buf, digits[r1], n+3)
+		stream.n = n + 6
+		return
+	}
+	r3 := q2 - q3*1000
+	q4 := q3 / 1000
+	if q4 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q3], n)
+		writeBuf(stream.buf, digits[r3], n)
+		writeBuf(stream.buf, digits[r2], n+3)
+		writeBuf(stream.buf, digits[r1], n+6)
+		stream.n = n + 9
+		return
+	}
+	r4 := q3 - q4*1000
+	q5 := q4 / 1000
+	if q5 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q4], n)
+		writeBuf(stream.buf, digits[r4], n)
+		writeBuf(stream.buf, digits[r3], n+3)
+		writeBuf(stream.buf, digits[r2], n+6)
+		writeBuf(stream.buf, digits[r1], n+9)
+		stream.n = n + 12
+		return
+	}
+	r5 := q4 - q5*1000
+	q6 := q5 / 1000
+	if q6 == 0 {
+		n = writeFirstBuf(stream.buf, digits[q5], n)
+	} else {
+		stream.buf[n] = byte(q6 + '0')
+		n++
+		r6 := q5 - q6*1000
+		writeBuf(stream.buf, digits[r6], n)
+		n += 3
+	}
+	writeBuf(stream.buf, digits[r5], n)
+	writeBuf(stream.buf, digits[r4], n+3)
+	writeBuf(stream.buf, digits[r3], n+6)
+	writeBuf(stream.buf, digits[r2], n+9)
+	writeBuf(stream.buf, digits[r1], n+12)
+	stream.n = n + 15
+}
+
+// WriteInt write int to stream
+func (stream *Stream) WriteInt(val int) {
+	stream.WriteInt64(int64(val))
+}
+
+// WriteUint write uint to stream
+func (stream *Stream) WriteUint(val uint) {
+	stream.WriteUint64(uint64(val))
+}
diff --git a/vendor/github.com/json-iterator/go/stream_str.go b/vendor/github.com/json-iterator/go/feature_stream_string.go
similarity index 91%
rename from vendor/github.com/json-iterator/go/stream_str.go
rename to vendor/github.com/json-iterator/go/feature_stream_string.go
index 54c2ba0b3..334282f05 100644
--- a/vendor/github.com/json-iterator/go/stream_str.go
+++ b/vendor/github.com/json-iterator/go/feature_stream_string.go
@@ -219,22 +219,34 @@ var hex = "0123456789abcdef"
 
 // WriteStringWithHTMLEscaped write string to stream with html special characters escaped
 func (stream *Stream) WriteStringWithHTMLEscaped(s string) {
+	stream.ensure(32)
 	valLen := len(s)
-	stream.buf = append(stream.buf, '"')
+	toWriteLen := valLen
+	bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
+	if stream.n+toWriteLen > bufLengthMinusTwo {
+		toWriteLen = bufLengthMinusTwo - stream.n
+	}
+	n := stream.n
+	stream.buf[n] = '"'
+	n++
 	// write string, the fast path, without utf8 and escape support
 	i := 0
-	for ; i < valLen; i++ {
+	for ; i < toWriteLen; i++ {
 		c := s[i]
 		if c < utf8.RuneSelf && htmlSafeSet[c] {
-			stream.buf = append(stream.buf, c)
+			stream.buf[n] = c
+			n++
 		} else {
 			break
 		}
 	}
 	if i == valLen {
-		stream.buf = append(stream.buf, '"')
+		stream.buf[n] = '"'
+		n++
+		stream.n = n
 		return
 	}
+	stream.n = n
 	writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen)
 }
 
@@ -309,22 +321,34 @@ func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen
 
 // WriteString write string to stream without html escape
 func (stream *Stream) WriteString(s string) {
+	stream.ensure(32)
 	valLen := len(s)
-	stream.buf = append(stream.buf, '"')
+	toWriteLen := valLen
+	bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
+	if stream.n+toWriteLen > bufLengthMinusTwo {
+		toWriteLen = bufLengthMinusTwo - stream.n
+	}
+	n := stream.n
+	stream.buf[n] = '"'
+	n++
 	// write string, the fast path, without utf8 and escape support
 	i := 0
-	for ; i < valLen; i++ {
+	for ; i < toWriteLen; i++ {
 		c := s[i]
 		if c > 31 && c != '"' && c != '\\' {
-			stream.buf = append(stream.buf, c)
+			stream.buf[n] = c
+			n++
 		} else {
 			break
 		}
 	}
 	if i == valLen {
-		stream.buf = append(stream.buf, '"')
+		stream.buf[n] = '"'
+		n++
+		stream.n = n
 		return
 	}
+	stream.n = n
 	writeStringSlowPath(stream, i, s, valLen)
 }
 
diff --git a/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md
new file mode 100644
index 000000000..3095662b0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md
@@ -0,0 +1,7 @@
+| json type \ dest type | bool | int | uint | float |string|
+| --- | --- | --- | --- |--|--|
+| number | positive => true <br/> negative => true <br/> zero => false| 23.2 => 23 <br/> -32.1 => -32| 12.1 => 12 <br/> -12.1 => 0|as normal|same as origin|
+| string | empty string => false <br/> string "0" => false <br/> other strings => true | "123.32" => 123 <br/> "-123.4" => -123 <br/> "123.23xxxw" => 123 <br/>  "abcde12" => 0 <br/> "-32.1" => -32| 13.2 => 13 <br/> -1.1 => 0 |12.1 => 12.1 <br/> -12.3 => -12.3<br/> 12.4xxa => 12.4 <br/> +1.1e2 =>110 |same as origin|
+| bool | true => true <br/> false => false| true => 1 <br/> false => 0 | true => 1 <br/> false => 0 |true => 1 <br/>false => 0|true => "true" <br/> false => "false"|
+| object | true | 0 | 0 |0|originnal json|
+| array | empty array => false <br/> nonempty array => true| [] => 0 <br/> [1,2] => 1 | [] => 0 <br/> [1,2] => 1 |[] => 0<br/>[1,2] => 1|original json|
\ No newline at end of file
diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go
deleted file mode 100644
index 4459e203f..000000000
--- a/vendor/github.com/json-iterator/go/reflect.go
+++ /dev/null
@@ -1,332 +0,0 @@
-package jsoniter
-
-import (
-	"fmt"
-	"reflect"
-	"unsafe"
-
-	"github.com/modern-go/reflect2"
-)
-
-// ValDecoder is an internal type registered to cache as needed.
-// Don't confuse jsoniter.ValDecoder with json.Decoder.
-// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link).
-//
-// Reflection on type to create decoders, which is then cached
-// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions
-// 1. create instance of new value, for example *int will need a int to be allocated
-// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New
-// 3. assignment to map, both key and value will be reflect.Value
-// For a simple struct binding, it will be reflect.Value free and allocation free
-type ValDecoder interface {
-	Decode(ptr unsafe.Pointer, iter *Iterator)
-}
-
-// ValEncoder is an internal type registered to cache as needed.
-// Don't confuse jsoniter.ValEncoder with json.Encoder.
-// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link).
-type ValEncoder interface {
-	IsEmpty(ptr unsafe.Pointer) bool
-	Encode(ptr unsafe.Pointer, stream *Stream)
-}
-
-type checkIsEmpty interface {
-	IsEmpty(ptr unsafe.Pointer) bool
-}
-
-type ctx struct {
-	*frozenConfig
-	prefix   string
-	encoders map[reflect2.Type]ValEncoder
-	decoders map[reflect2.Type]ValDecoder
-}
-
-func (b *ctx) caseSensitive() bool {
-	if b.frozenConfig == nil {
-		// default is case-insensitive
-		return false
-	}
-	return b.frozenConfig.caseSensitive
-}
-
-func (b *ctx) append(prefix string) *ctx {
-	return &ctx{
-		frozenConfig: b.frozenConfig,
-		prefix:       b.prefix + " " + prefix,
-		encoders:     b.encoders,
-		decoders:     b.decoders,
-	}
-}
-
-// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
-func (iter *Iterator) ReadVal(obj interface{}) {
-	cacheKey := reflect2.RTypeOf(obj)
-	decoder := iter.cfg.getDecoderFromCache(cacheKey)
-	if decoder == nil {
-		typ := reflect2.TypeOf(obj)
-		if typ.Kind() != reflect.Ptr {
-			iter.ReportError("ReadVal", "can only unmarshal into pointer")
-			return
-		}
-		decoder = iter.cfg.DecoderOf(typ)
-	}
-	ptr := reflect2.PtrOf(obj)
-	if ptr == nil {
-		iter.ReportError("ReadVal", "can not read into nil pointer")
-		return
-	}
-	decoder.Decode(ptr, iter)
-}
-
-// WriteVal copy the go interface into underlying JSON, same as json.Marshal
-func (stream *Stream) WriteVal(val interface{}) {
-	if nil == val {
-		stream.WriteNil()
-		return
-	}
-	cacheKey := reflect2.RTypeOf(val)
-	encoder := stream.cfg.getEncoderFromCache(cacheKey)
-	if encoder == nil {
-		typ := reflect2.TypeOf(val)
-		encoder = stream.cfg.EncoderOf(typ)
-	}
-	encoder.Encode(reflect2.PtrOf(val), stream)
-}
-
-func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder {
-	cacheKey := typ.RType()
-	decoder := cfg.getDecoderFromCache(cacheKey)
-	if decoder != nil {
-		return decoder
-	}
-	ctx := &ctx{
-		frozenConfig: cfg,
-		prefix:       "",
-		decoders:     map[reflect2.Type]ValDecoder{},
-		encoders:     map[reflect2.Type]ValEncoder{},
-	}
-	ptrType := typ.(*reflect2.UnsafePtrType)
-	decoder = decoderOfType(ctx, ptrType.Elem())
-	cfg.addDecoderToCache(cacheKey, decoder)
-	return decoder
-}
-
-func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
-	decoder := getTypeDecoderFromExtension(ctx, typ)
-	if decoder != nil {
-		return decoder
-	}
-	decoder = createDecoderOfType(ctx, typ)
-	for _, extension := range extensions {
-		decoder = extension.DecorateDecoder(typ, decoder)
-	}
-	decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder)
-	for _, extension := range ctx.extraExtensions {
-		decoder = extension.DecorateDecoder(typ, decoder)
-	}
-	return decoder
-}
-
-func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
-	decoder := ctx.decoders[typ]
-	if decoder != nil {
-		return decoder
-	}
-	placeholder := &placeholderDecoder{}
-	ctx.decoders[typ] = placeholder
-	decoder = _createDecoderOfType(ctx, typ)
-	placeholder.decoder = decoder
-	return decoder
-}
-
-func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
-	decoder := createDecoderOfJsonRawMessage(ctx, typ)
-	if decoder != nil {
-		return decoder
-	}
-	decoder = createDecoderOfJsonNumber(ctx, typ)
-	if decoder != nil {
-		return decoder
-	}
-	decoder = createDecoderOfMarshaler(ctx, typ)
-	if decoder != nil {
-		return decoder
-	}
-	decoder = createDecoderOfAny(ctx, typ)
-	if decoder != nil {
-		return decoder
-	}
-	decoder = createDecoderOfNative(ctx, typ)
-	if decoder != nil {
-		return decoder
-	}
-	switch typ.Kind() {
-	case reflect.Interface:
-		ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType)
-		if isIFace {
-			return &ifaceDecoder{valType: ifaceType}
-		}
-		return &efaceDecoder{}
-	case reflect.Struct:
-		return decoderOfStruct(ctx, typ)
-	case reflect.Array:
-		return decoderOfArray(ctx, typ)
-	case reflect.Slice:
-		return decoderOfSlice(ctx, typ)
-	case reflect.Map:
-		return decoderOfMap(ctx, typ)
-	case reflect.Ptr:
-		return decoderOfOptional(ctx, typ)
-	default:
-		return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())}
-	}
-}
-
-func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder {
-	cacheKey := typ.RType()
-	encoder := cfg.getEncoderFromCache(cacheKey)
-	if encoder != nil {
-		return encoder
-	}
-	ctx := &ctx{
-		frozenConfig: cfg,
-		prefix:       "",
-		decoders:     map[reflect2.Type]ValDecoder{},
-		encoders:     map[reflect2.Type]ValEncoder{},
-	}
-	encoder = encoderOfType(ctx, typ)
-	if typ.LikePtr() {
-		encoder = &onePtrEncoder{encoder}
-	}
-	cfg.addEncoderToCache(cacheKey, encoder)
-	return encoder
-}
-
-type onePtrEncoder struct {
-	encoder ValEncoder
-}
-
-func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
-}
-
-func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
-}
-
-func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
-	encoder := getTypeEncoderFromExtension(ctx, typ)
-	if encoder != nil {
-		return encoder
-	}
-	encoder = createEncoderOfType(ctx, typ)
-	for _, extension := range extensions {
-		encoder = extension.DecorateEncoder(typ, encoder)
-	}
-	encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder)
-	for _, extension := range ctx.extraExtensions {
-		encoder = extension.DecorateEncoder(typ, encoder)
-	}
-	return encoder
-}
-
-func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
-	encoder := ctx.encoders[typ]
-	if encoder != nil {
-		return encoder
-	}
-	placeholder := &placeholderEncoder{}
-	ctx.encoders[typ] = placeholder
-	encoder = _createEncoderOfType(ctx, typ)
-	placeholder.encoder = encoder
-	return encoder
-}
-func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
-	encoder := createEncoderOfJsonRawMessage(ctx, typ)
-	if encoder != nil {
-		return encoder
-	}
-	encoder = createEncoderOfJsonNumber(ctx, typ)
-	if encoder != nil {
-		return encoder
-	}
-	encoder = createEncoderOfMarshaler(ctx, typ)
-	if encoder != nil {
-		return encoder
-	}
-	encoder = createEncoderOfAny(ctx, typ)
-	if encoder != nil {
-		return encoder
-	}
-	encoder = createEncoderOfNative(ctx, typ)
-	if encoder != nil {
-		return encoder
-	}
-	kind := typ.Kind()
-	switch kind {
-	case reflect.Interface:
-		return &dynamicEncoder{typ}
-	case reflect.Struct:
-		return encoderOfStruct(ctx, typ)
-	case reflect.Array:
-		return encoderOfArray(ctx, typ)
-	case reflect.Slice:
-		return encoderOfSlice(ctx, typ)
-	case reflect.Map:
-		return encoderOfMap(ctx, typ)
-	case reflect.Ptr:
-		return encoderOfOptional(ctx, typ)
-	default:
-		return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())}
-	}
-}
-
-type lazyErrorDecoder struct {
-	err error
-}
-
-func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if iter.WhatIsNext() != NilValue {
-		if iter.Error == nil {
-			iter.Error = decoder.err
-		}
-	} else {
-		iter.Skip()
-	}
-}
-
-type lazyErrorEncoder struct {
-	err error
-}
-
-func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	if ptr == nil {
-		stream.WriteNil()
-	} else if stream.Error == nil {
-		stream.Error = encoder.err
-	}
-}
-
-func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return false
-}
-
-type placeholderDecoder struct {
-	decoder ValDecoder
-}
-
-func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	decoder.decoder.Decode(ptr, iter)
-}
-
-type placeholderEncoder struct {
-	encoder ValEncoder
-}
-
-func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	encoder.encoder.Encode(ptr, stream)
-}
-
-func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.encoder.IsEmpty(ptr)
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go
deleted file mode 100644
index 13a0b7b08..000000000
--- a/vendor/github.com/json-iterator/go/reflect_array.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package jsoniter
-
-import (
-	"fmt"
-	"github.com/modern-go/reflect2"
-	"io"
-	"unsafe"
-)
-
-func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
-	arrayType := typ.(*reflect2.UnsafeArrayType)
-	decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
-	return &arrayDecoder{arrayType, decoder}
-}
-
-func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
-	arrayType := typ.(*reflect2.UnsafeArrayType)
-	if arrayType.Len() == 0 {
-		return emptyArrayEncoder{}
-	}
-	encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
-	return &arrayEncoder{arrayType, encoder}
-}
-
-type emptyArrayEncoder struct{}
-
-func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteEmptyArray()
-}
-
-func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return true
-}
-
-type arrayEncoder struct {
-	arrayType   *reflect2.UnsafeArrayType
-	elemEncoder ValEncoder
-}
-
-func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteArrayStart()
-	elemPtr := unsafe.Pointer(ptr)
-	encoder.elemEncoder.Encode(elemPtr, stream)
-	for i := 1; i < encoder.arrayType.Len(); i++ {
-		stream.WriteMore()
-		elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
-		encoder.elemEncoder.Encode(elemPtr, stream)
-	}
-	stream.WriteArrayEnd()
-	if stream.Error != nil && stream.Error != io.EOF {
-		stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
-	}
-}
-
-func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return false
-}
-
-type arrayDecoder struct {
-	arrayType   *reflect2.UnsafeArrayType
-	elemDecoder ValDecoder
-}
-
-func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	decoder.doDecode(ptr, iter)
-	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
-	}
-}
-
-func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
-	c := iter.nextToken()
-	arrayType := decoder.arrayType
-	if c == 'n' {
-		iter.skipThreeBytes('u', 'l', 'l')
-		return
-	}
-	if c != '[' {
-		iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
-		return
-	}
-	c = iter.nextToken()
-	if c == ']' {
-		return
-	}
-	iter.unreadByte()
-	elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
-	decoder.elemDecoder.Decode(elemPtr, iter)
-	length := 1
-	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
-		if length >= arrayType.Len() {
-			iter.Skip()
-			continue
-		}
-		idx := length
-		length += 1
-		elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
-		decoder.elemDecoder.Decode(elemPtr, iter)
-	}
-	if c != ']' {
-		iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
-		return
-	}
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go
deleted file mode 100644
index 8b6bc8b43..000000000
--- a/vendor/github.com/json-iterator/go/reflect_dynamic.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package jsoniter
-
-import (
-	"github.com/modern-go/reflect2"
-	"reflect"
-	"unsafe"
-)
-
-type dynamicEncoder struct {
-	valType reflect2.Type
-}
-
-func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	obj := encoder.valType.UnsafeIndirect(ptr)
-	stream.WriteVal(obj)
-}
-
-func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.valType.UnsafeIndirect(ptr) == nil
-}
-
-type efaceDecoder struct {
-}
-
-func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	pObj := (*interface{})(ptr)
-	obj := *pObj
-	if obj == nil {
-		*pObj = iter.Read()
-		return
-	}
-	typ := reflect2.TypeOf(obj)
-	if typ.Kind() != reflect.Ptr {
-		*pObj = iter.Read()
-		return
-	}
-	ptrType := typ.(*reflect2.UnsafePtrType)
-	ptrElemType := ptrType.Elem()
-	if iter.WhatIsNext() == NilValue {
-		if ptrElemType.Kind() != reflect.Ptr {
-			iter.skipFourBytes('n', 'u', 'l', 'l')
-			*pObj = nil
-			return
-		}
-	}
-	if reflect2.IsNil(obj) {
-		obj := ptrElemType.New()
-		iter.ReadVal(obj)
-		*pObj = obj
-		return
-	}
-	iter.ReadVal(obj)
-}
-
-type ifaceDecoder struct {
-	valType *reflect2.UnsafeIFaceType
-}
-
-func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if iter.ReadNil() {
-		decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew())
-		return
-	}
-	obj := decoder.valType.UnsafeIndirect(ptr)
-	if reflect2.IsNil(obj) {
-		iter.ReportError("decode non empty interface", "can not unmarshal into nil")
-		return
-	}
-	iter.ReadVal(obj)
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go
deleted file mode 100644
index 98d45c1ec..000000000
--- a/vendor/github.com/json-iterator/go/reflect_json_number.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package jsoniter
-
-import (
-	"encoding/json"
-	"github.com/modern-go/reflect2"
-	"strconv"
-	"unsafe"
-)
-
-type Number string
-
-// String returns the literal text of the number.
-func (n Number) String() string { return string(n) }
-
-// Float64 returns the number as a float64.
-func (n Number) Float64() (float64, error) {
-	return strconv.ParseFloat(string(n), 64)
-}
-
-// Int64 returns the number as an int64.
-func (n Number) Int64() (int64, error) {
-	return strconv.ParseInt(string(n), 10, 64)
-}
-
-func CastJsonNumber(val interface{}) (string, bool) {
-	switch typedVal := val.(type) {
-	case json.Number:
-		return string(typedVal), true
-	case Number:
-		return string(typedVal), true
-	}
-	return "", false
-}
-
-var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem()
-var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem()
-
-func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder {
-	if typ.AssignableTo(jsonNumberType) {
-		return &jsonNumberCodec{}
-	}
-	if typ.AssignableTo(jsoniterNumberType) {
-		return &jsoniterNumberCodec{}
-	}
-	return nil
-}
-
-func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder {
-	if typ.AssignableTo(jsonNumberType) {
-		return &jsonNumberCodec{}
-	}
-	if typ.AssignableTo(jsoniterNumberType) {
-		return &jsoniterNumberCodec{}
-	}
-	return nil
-}
-
-type jsonNumberCodec struct {
-}
-
-func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	switch iter.WhatIsNext() {
-	case StringValue:
-		*((*json.Number)(ptr)) = json.Number(iter.ReadString())
-	case NilValue:
-		iter.skipFourBytes('n', 'u', 'l', 'l')
-		*((*json.Number)(ptr)) = ""
-	default:
-		*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
-	}
-}
-
-func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	number := *((*json.Number)(ptr))
-	if len(number) == 0 {
-		stream.writeByte('0')
-	} else {
-		stream.WriteRaw(string(number))
-	}
-}
-
-func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	return len(*((*json.Number)(ptr))) == 0
-}
-
-type jsoniterNumberCodec struct {
-}
-
-func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	switch iter.WhatIsNext() {
-	case StringValue:
-		*((*Number)(ptr)) = Number(iter.ReadString())
-	case NilValue:
-		iter.skipFourBytes('n', 'u', 'l', 'l')
-		*((*Number)(ptr)) = ""
-	default:
-		*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
-	}
-}
-
-func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	number := *((*Number)(ptr))
-	if len(number) == 0 {
-		stream.writeByte('0')
-	} else {
-		stream.WriteRaw(string(number))
-	}
-}
-
-func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	return len(*((*Number)(ptr))) == 0
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go
deleted file mode 100644
index f2619936c..000000000
--- a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package jsoniter
-
-import (
-	"encoding/json"
-	"github.com/modern-go/reflect2"
-	"unsafe"
-)
-
-var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()
-var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()
-
-func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder {
-	if typ == jsonRawMessageType {
-		return &jsonRawMessageCodec{}
-	}
-	if typ == jsoniterRawMessageType {
-		return &jsoniterRawMessageCodec{}
-	}
-	return nil
-}
-
-func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder {
-	if typ == jsonRawMessageType {
-		return &jsonRawMessageCodec{}
-	}
-	if typ == jsoniterRawMessageType {
-		return &jsoniterRawMessageCodec{}
-	}
-	return nil
-}
-
-type jsonRawMessageCodec struct {
-}
-
-func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	*((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
-}
-
-func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
-}
-
-func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	return len(*((*json.RawMessage)(ptr))) == 0
-}
-
-type jsoniterRawMessageCodec struct {
-}
-
-func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	*((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
-}
-
-func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteRaw(string(*((*RawMessage)(ptr))))
-}
-
-func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	return len(*((*RawMessage)(ptr))) == 0
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go
deleted file mode 100644
index 7f66a88b0..000000000
--- a/vendor/github.com/json-iterator/go/reflect_map.go
+++ /dev/null
@@ -1,326 +0,0 @@
-package jsoniter
-
-import (
-	"fmt"
-	"github.com/modern-go/reflect2"
-	"io"
-	"reflect"
-	"sort"
-	"unsafe"
-)
-
-func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
-	mapType := typ.(*reflect2.UnsafeMapType)
-	keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key())
-	elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem())
-	return &mapDecoder{
-		mapType:     mapType,
-		keyType:     mapType.Key(),
-		elemType:    mapType.Elem(),
-		keyDecoder:  keyDecoder,
-		elemDecoder: elemDecoder,
-	}
-}
-
-func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
-	mapType := typ.(*reflect2.UnsafeMapType)
-	if ctx.sortMapKeys {
-		return &sortKeysMapEncoder{
-			mapType:     mapType,
-			keyEncoder:  encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
-			elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
-		}
-	}
-	return &mapEncoder{
-		mapType:     mapType,
-		keyEncoder:  encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
-		elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
-	}
-}
-
-func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
-	decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ)
-	if decoder != nil {
-		return decoder
-	}
-	for _, extension := range ctx.extraExtensions {
-		decoder := extension.CreateMapKeyDecoder(typ)
-		if decoder != nil {
-			return decoder
-		}
-	}
-	switch typ.Kind() {
-	case reflect.String:
-		return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
-	case reflect.Bool,
-		reflect.Uint8, reflect.Int8,
-		reflect.Uint16, reflect.Int16,
-		reflect.Uint32, reflect.Int32,
-		reflect.Uint64, reflect.Int64,
-		reflect.Uint, reflect.Int,
-		reflect.Float32, reflect.Float64,
-		reflect.Uintptr:
-		typ = reflect2.DefaultTypeOfKind(typ.Kind())
-		return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
-	default:
-		ptrType := reflect2.PtrTo(typ)
-		if ptrType.Implements(textMarshalerType) {
-			return &referenceDecoder{
-				&textUnmarshalerDecoder{
-					valType: ptrType,
-				},
-			}
-		}
-		if typ.Implements(textMarshalerType) {
-			return &textUnmarshalerDecoder{
-				valType: typ,
-			}
-		}
-		return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
-	}
-}
-
-func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
-	encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ)
-	if encoder != nil {
-		return encoder
-	}
-	for _, extension := range ctx.extraExtensions {
-		encoder := extension.CreateMapKeyEncoder(typ)
-		if encoder != nil {
-			return encoder
-		}
-	}
-	switch typ.Kind() {
-	case reflect.String:
-		return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
-	case reflect.Bool,
-		reflect.Uint8, reflect.Int8,
-		reflect.Uint16, reflect.Int16,
-		reflect.Uint32, reflect.Int32,
-		reflect.Uint64, reflect.Int64,
-		reflect.Uint, reflect.Int,
-		reflect.Float32, reflect.Float64,
-		reflect.Uintptr:
-		typ = reflect2.DefaultTypeOfKind(typ.Kind())
-		return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
-	default:
-		if typ == textMarshalerType {
-			return &directTextMarshalerEncoder{
-				stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
-			}
-		}
-		if typ.Implements(textMarshalerType) {
-			return &textMarshalerEncoder{
-				valType:       typ,
-				stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
-			}
-		}
-		if typ.Kind() == reflect.Interface {
-			return &dynamicMapKeyEncoder{ctx, typ}
-		}
-		return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
-	}
-}
-
-type mapDecoder struct {
-	mapType     *reflect2.UnsafeMapType
-	keyType     reflect2.Type
-	elemType    reflect2.Type
-	keyDecoder  ValDecoder
-	elemDecoder ValDecoder
-}
-
-func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	mapType := decoder.mapType
-	c := iter.nextToken()
-	if c == 'n' {
-		iter.skipThreeBytes('u', 'l', 'l')
-		*(*unsafe.Pointer)(ptr) = nil
-		mapType.UnsafeSet(ptr, mapType.UnsafeNew())
-		return
-	}
-	if mapType.UnsafeIsNil(ptr) {
-		mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
-	}
-	if c != '{' {
-		iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
-		return
-	}
-	c = iter.nextToken()
-	if c == '}' {
-		return
-	}
-	if c != '"' {
-		iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
-		return
-	}
-	iter.unreadByte()
-	key := decoder.keyType.UnsafeNew()
-	decoder.keyDecoder.Decode(key, iter)
-	c = iter.nextToken()
-	if c != ':' {
-		iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
-		return
-	}
-	elem := decoder.elemType.UnsafeNew()
-	decoder.elemDecoder.Decode(elem, iter)
-	decoder.mapType.UnsafeSetIndex(ptr, key, elem)
-	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
-		key := decoder.keyType.UnsafeNew()
-		decoder.keyDecoder.Decode(key, iter)
-		c = iter.nextToken()
-		if c != ':' {
-			iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
-			return
-		}
-		elem := decoder.elemType.UnsafeNew()
-		decoder.elemDecoder.Decode(elem, iter)
-		decoder.mapType.UnsafeSetIndex(ptr, key, elem)
-	}
-	if c != '}' {
-		iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
-	}
-}
-
-type numericMapKeyDecoder struct {
-	decoder ValDecoder
-}
-
-func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	c := iter.nextToken()
-	if c != '"' {
-		iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
-		return
-	}
-	decoder.decoder.Decode(ptr, iter)
-	c = iter.nextToken()
-	if c != '"' {
-		iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
-		return
-	}
-}
-
-type numericMapKeyEncoder struct {
-	encoder ValEncoder
-}
-
-func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.writeByte('"')
-	encoder.encoder.Encode(ptr, stream)
-	stream.writeByte('"')
-}
-
-func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return false
-}
-
-type dynamicMapKeyEncoder struct {
-	ctx     *ctx
-	valType reflect2.Type
-}
-
-func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	obj := encoder.valType.UnsafeIndirect(ptr)
-	encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
-}
-
-func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	obj := encoder.valType.UnsafeIndirect(ptr)
-	return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
-}
-
-type mapEncoder struct {
-	mapType     *reflect2.UnsafeMapType
-	keyEncoder  ValEncoder
-	elemEncoder ValEncoder
-}
-
-func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteObjectStart()
-	iter := encoder.mapType.UnsafeIterate(ptr)
-	for i := 0; iter.HasNext(); i++ {
-		if i != 0 {
-			stream.WriteMore()
-		}
-		key, elem := iter.UnsafeNext()
-		encoder.keyEncoder.Encode(key, stream)
-		if stream.indention > 0 {
-			stream.writeTwoBytes(byte(':'), byte(' '))
-		} else {
-			stream.writeByte(':')
-		}
-		encoder.elemEncoder.Encode(elem, stream)
-	}
-	stream.WriteObjectEnd()
-}
-
-func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	iter := encoder.mapType.UnsafeIterate(ptr)
-	return !iter.HasNext()
-}
-
-type sortKeysMapEncoder struct {
-	mapType     *reflect2.UnsafeMapType
-	keyEncoder  ValEncoder
-	elemEncoder ValEncoder
-}
-
-func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	if *(*unsafe.Pointer)(ptr) == nil {
-		stream.WriteNil()
-		return
-	}
-	stream.WriteObjectStart()
-	mapIter := encoder.mapType.UnsafeIterate(ptr)
-	subStream := stream.cfg.BorrowStream(nil)
-	subIter := stream.cfg.BorrowIterator(nil)
-	keyValues := encodedKeyValues{}
-	for mapIter.HasNext() {
-		subStream.buf = make([]byte, 0, 64)
-		key, elem := mapIter.UnsafeNext()
-		encoder.keyEncoder.Encode(key, subStream)
-		if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
-			stream.Error = subStream.Error
-		}
-		encodedKey := subStream.Buffer()
-		subIter.ResetBytes(encodedKey)
-		decodedKey := subIter.ReadString()
-		if stream.indention > 0 {
-			subStream.writeTwoBytes(byte(':'), byte(' '))
-		} else {
-			subStream.writeByte(':')
-		}
-		encoder.elemEncoder.Encode(elem, subStream)
-		keyValues = append(keyValues, encodedKV{
-			key:      decodedKey,
-			keyValue: subStream.Buffer(),
-		})
-	}
-	sort.Sort(keyValues)
-	for i, keyValue := range keyValues {
-		if i != 0 {
-			stream.WriteMore()
-		}
-		stream.Write(keyValue.keyValue)
-	}
-	stream.WriteObjectEnd()
-	stream.cfg.ReturnStream(subStream)
-	stream.cfg.ReturnIterator(subIter)
-}
-
-func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	iter := encoder.mapType.UnsafeIterate(ptr)
-	return !iter.HasNext()
-}
-
-type encodedKeyValues []encodedKV
-
-type encodedKV struct {
-	key      string
-	keyValue []byte
-}
-
-func (sv encodedKeyValues) Len() int           { return len(sv) }
-func (sv encodedKeyValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
-func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }
diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go
deleted file mode 100644
index 58ac959ad..000000000
--- a/vendor/github.com/json-iterator/go/reflect_marshaler.go
+++ /dev/null
@@ -1,218 +0,0 @@
-package jsoniter
-
-import (
-	"encoding"
-	"encoding/json"
-	"github.com/modern-go/reflect2"
-	"unsafe"
-)
-
-var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
-var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem()
-var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem()
-var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem()
-
-func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder {
-	ptrType := reflect2.PtrTo(typ)
-	if ptrType.Implements(unmarshalerType) {
-		return &referenceDecoder{
-			&unmarshalerDecoder{ptrType},
-		}
-	}
-	if ptrType.Implements(textUnmarshalerType) {
-		return &referenceDecoder{
-			&textUnmarshalerDecoder{ptrType},
-		}
-	}
-	return nil
-}
-
-func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder {
-	if typ == marshalerType {
-		checkIsEmpty := createCheckIsEmpty(ctx, typ)
-		var encoder ValEncoder = &directMarshalerEncoder{
-			checkIsEmpty: checkIsEmpty,
-		}
-		return encoder
-	}
-	if typ.Implements(marshalerType) {
-		checkIsEmpty := createCheckIsEmpty(ctx, typ)
-		var encoder ValEncoder = &marshalerEncoder{
-			valType:      typ,
-			checkIsEmpty: checkIsEmpty,
-		}
-		return encoder
-	}
-	ptrType := reflect2.PtrTo(typ)
-	if ctx.prefix != "" && ptrType.Implements(marshalerType) {
-		checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
-		var encoder ValEncoder = &marshalerEncoder{
-			valType:      ptrType,
-			checkIsEmpty: checkIsEmpty,
-		}
-		return &referenceEncoder{encoder}
-	}
-	if typ == textMarshalerType {
-		checkIsEmpty := createCheckIsEmpty(ctx, typ)
-		var encoder ValEncoder = &directTextMarshalerEncoder{
-			checkIsEmpty:  checkIsEmpty,
-			stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
-		}
-		return encoder
-	}
-	if typ.Implements(textMarshalerType) {
-		checkIsEmpty := createCheckIsEmpty(ctx, typ)
-		var encoder ValEncoder = &textMarshalerEncoder{
-			valType:       typ,
-			stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
-			checkIsEmpty:  checkIsEmpty,
-		}
-		return encoder
-	}
-	// if prefix is empty, the type is the root type
-	if ctx.prefix != "" && ptrType.Implements(textMarshalerType) {
-		checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
-		var encoder ValEncoder = &textMarshalerEncoder{
-			valType:       ptrType,
-			stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
-			checkIsEmpty:  checkIsEmpty,
-		}
-		return &referenceEncoder{encoder}
-	}
-	return nil
-}
-
-type marshalerEncoder struct {
-	checkIsEmpty checkIsEmpty
-	valType      reflect2.Type
-}
-
-func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	obj := encoder.valType.UnsafeIndirect(ptr)
-	if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
-		stream.WriteNil()
-		return
-	}
-	marshaler := obj.(json.Marshaler)
-	bytes, err := marshaler.MarshalJSON()
-	if err != nil {
-		stream.Error = err
-	} else {
-		stream.Write(bytes)
-	}
-}
-
-func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.checkIsEmpty.IsEmpty(ptr)
-}
-
-type directMarshalerEncoder struct {
-	checkIsEmpty checkIsEmpty
-}
-
-func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	marshaler := *(*json.Marshaler)(ptr)
-	if marshaler == nil {
-		stream.WriteNil()
-		return
-	}
-	bytes, err := marshaler.MarshalJSON()
-	if err != nil {
-		stream.Error = err
-	} else {
-		stream.Write(bytes)
-	}
-}
-
-func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.checkIsEmpty.IsEmpty(ptr)
-}
-
-type textMarshalerEncoder struct {
-	valType       reflect2.Type
-	stringEncoder ValEncoder
-	checkIsEmpty  checkIsEmpty
-}
-
-func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	obj := encoder.valType.UnsafeIndirect(ptr)
-	if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
-		stream.WriteNil()
-		return
-	}
-	marshaler := (obj).(encoding.TextMarshaler)
-	bytes, err := marshaler.MarshalText()
-	if err != nil {
-		stream.Error = err
-	} else {
-		str := string(bytes)
-		encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
-	}
-}
-
-func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.checkIsEmpty.IsEmpty(ptr)
-}
-
-type directTextMarshalerEncoder struct {
-	stringEncoder ValEncoder
-	checkIsEmpty  checkIsEmpty
-}
-
-func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	marshaler := *(*encoding.TextMarshaler)(ptr)
-	if marshaler == nil {
-		stream.WriteNil()
-		return
-	}
-	bytes, err := marshaler.MarshalText()
-	if err != nil {
-		stream.Error = err
-	} else {
-		str := string(bytes)
-		encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
-	}
-}
-
-func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.checkIsEmpty.IsEmpty(ptr)
-}
-
-type unmarshalerDecoder struct {
-	valType reflect2.Type
-}
-
-func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	valType := decoder.valType
-	obj := valType.UnsafeIndirect(ptr)
-	unmarshaler := obj.(json.Unmarshaler)
-	iter.nextToken()
-	iter.unreadByte() // skip spaces
-	bytes := iter.SkipAndReturnBytes()
-	err := unmarshaler.UnmarshalJSON(bytes)
-	if err != nil {
-		iter.ReportError("unmarshalerDecoder", err.Error())
-	}
-}
-
-type textUnmarshalerDecoder struct {
-	valType reflect2.Type
-}
-
-func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	valType := decoder.valType
-	obj := valType.UnsafeIndirect(ptr)
-	if reflect2.IsNil(obj) {
-		ptrType := valType.(*reflect2.UnsafePtrType)
-		elemType := ptrType.Elem()
-		elem := elemType.UnsafeNew()
-		ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem))
-		obj = valType.UnsafeIndirect(ptr)
-	}
-	unmarshaler := (obj).(encoding.TextUnmarshaler)
-	str := iter.ReadString()
-	err := unmarshaler.UnmarshalText([]byte(str))
-	if err != nil {
-		iter.ReportError("textUnmarshalerDecoder", err.Error())
-	}
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go
deleted file mode 100644
index 9042eb0cb..000000000
--- a/vendor/github.com/json-iterator/go/reflect_native.go
+++ /dev/null
@@ -1,451 +0,0 @@
-package jsoniter
-
-import (
-	"encoding/base64"
-	"reflect"
-	"strconv"
-	"unsafe"
-
-	"github.com/modern-go/reflect2"
-)
-
-const ptrSize = 32 << uintptr(^uintptr(0)>>63)
-
-func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
-	if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
-		sliceDecoder := decoderOfSlice(ctx, typ)
-		return &base64Codec{sliceDecoder: sliceDecoder}
-	}
-	typeName := typ.String()
-	kind := typ.Kind()
-	switch kind {
-	case reflect.String:
-		if typeName != "string" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
-		}
-		return &stringCodec{}
-	case reflect.Int:
-		if typeName != "int" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
-		}
-		if strconv.IntSize == 32 {
-			return &int32Codec{}
-		}
-		return &int64Codec{}
-	case reflect.Int8:
-		if typeName != "int8" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
-		}
-		return &int8Codec{}
-	case reflect.Int16:
-		if typeName != "int16" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
-		}
-		return &int16Codec{}
-	case reflect.Int32:
-		if typeName != "int32" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
-		}
-		return &int32Codec{}
-	case reflect.Int64:
-		if typeName != "int64" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
-		}
-		return &int64Codec{}
-	case reflect.Uint:
-		if typeName != "uint" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
-		}
-		if strconv.IntSize == 32 {
-			return &uint32Codec{}
-		}
-		return &uint64Codec{}
-	case reflect.Uint8:
-		if typeName != "uint8" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
-		}
-		return &uint8Codec{}
-	case reflect.Uint16:
-		if typeName != "uint16" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
-		}
-		return &uint16Codec{}
-	case reflect.Uint32:
-		if typeName != "uint32" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
-		}
-		return &uint32Codec{}
-	case reflect.Uintptr:
-		if typeName != "uintptr" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
-		}
-		if ptrSize == 32 {
-			return &uint32Codec{}
-		}
-		return &uint64Codec{}
-	case reflect.Uint64:
-		if typeName != "uint64" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
-		}
-		return &uint64Codec{}
-	case reflect.Float32:
-		if typeName != "float32" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
-		}
-		return &float32Codec{}
-	case reflect.Float64:
-		if typeName != "float64" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
-		}
-		return &float64Codec{}
-	case reflect.Bool:
-		if typeName != "bool" {
-			return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
-		}
-		return &boolCodec{}
-	}
-	return nil
-}
-
-func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
-	if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
-		sliceDecoder := decoderOfSlice(ctx, typ)
-		return &base64Codec{sliceDecoder: sliceDecoder}
-	}
-	typeName := typ.String()
-	switch typ.Kind() {
-	case reflect.String:
-		if typeName != "string" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
-		}
-		return &stringCodec{}
-	case reflect.Int:
-		if typeName != "int" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
-		}
-		if strconv.IntSize == 32 {
-			return &int32Codec{}
-		}
-		return &int64Codec{}
-	case reflect.Int8:
-		if typeName != "int8" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
-		}
-		return &int8Codec{}
-	case reflect.Int16:
-		if typeName != "int16" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
-		}
-		return &int16Codec{}
-	case reflect.Int32:
-		if typeName != "int32" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
-		}
-		return &int32Codec{}
-	case reflect.Int64:
-		if typeName != "int64" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
-		}
-		return &int64Codec{}
-	case reflect.Uint:
-		if typeName != "uint" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
-		}
-		if strconv.IntSize == 32 {
-			return &uint32Codec{}
-		}
-		return &uint64Codec{}
-	case reflect.Uint8:
-		if typeName != "uint8" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
-		}
-		return &uint8Codec{}
-	case reflect.Uint16:
-		if typeName != "uint16" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
-		}
-		return &uint16Codec{}
-	case reflect.Uint32:
-		if typeName != "uint32" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
-		}
-		return &uint32Codec{}
-	case reflect.Uintptr:
-		if typeName != "uintptr" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
-		}
-		if ptrSize == 32 {
-			return &uint32Codec{}
-		}
-		return &uint64Codec{}
-	case reflect.Uint64:
-		if typeName != "uint64" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
-		}
-		return &uint64Codec{}
-	case reflect.Float32:
-		if typeName != "float32" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
-		}
-		return &float32Codec{}
-	case reflect.Float64:
-		if typeName != "float64" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
-		}
-		return &float64Codec{}
-	case reflect.Bool:
-		if typeName != "bool" {
-			return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
-		}
-		return &boolCodec{}
-	}
-	return nil
-}
-
-type stringCodec struct {
-}
-
-func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	*((*string)(ptr)) = iter.ReadString()
-}
-
-func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	str := *((*string)(ptr))
-	stream.WriteString(str)
-}
-
-func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*string)(ptr)) == ""
-}
-
-type int8Codec struct {
-}
-
-func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*int8)(ptr)) = iter.ReadInt8()
-	}
-}
-
-func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteInt8(*((*int8)(ptr)))
-}
-
-func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*int8)(ptr)) == 0
-}
-
-type int16Codec struct {
-}
-
-func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*int16)(ptr)) = iter.ReadInt16()
-	}
-}
-
-func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteInt16(*((*int16)(ptr)))
-}
-
-func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*int16)(ptr)) == 0
-}
-
-type int32Codec struct {
-}
-
-func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*int32)(ptr)) = iter.ReadInt32()
-	}
-}
-
-func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteInt32(*((*int32)(ptr)))
-}
-
-func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*int32)(ptr)) == 0
-}
-
-type int64Codec struct {
-}
-
-func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*int64)(ptr)) = iter.ReadInt64()
-	}
-}
-
-func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteInt64(*((*int64)(ptr)))
-}
-
-func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*int64)(ptr)) == 0
-}
-
-type uint8Codec struct {
-}
-
-func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*uint8)(ptr)) = iter.ReadUint8()
-	}
-}
-
-func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteUint8(*((*uint8)(ptr)))
-}
-
-func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*uint8)(ptr)) == 0
-}
-
-type uint16Codec struct {
-}
-
-func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*uint16)(ptr)) = iter.ReadUint16()
-	}
-}
-
-func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteUint16(*((*uint16)(ptr)))
-}
-
-func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*uint16)(ptr)) == 0
-}
-
-type uint32Codec struct {
-}
-
-func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*uint32)(ptr)) = iter.ReadUint32()
-	}
-}
-
-func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteUint32(*((*uint32)(ptr)))
-}
-
-func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*uint32)(ptr)) == 0
-}
-
-type uint64Codec struct {
-}
-
-func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*uint64)(ptr)) = iter.ReadUint64()
-	}
-}
-
-func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteUint64(*((*uint64)(ptr)))
-}
-
-func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*uint64)(ptr)) == 0
-}
-
-type float32Codec struct {
-}
-
-func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*float32)(ptr)) = iter.ReadFloat32()
-	}
-}
-
-func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteFloat32(*((*float32)(ptr)))
-}
-
-func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*float32)(ptr)) == 0
-}
-
-type float64Codec struct {
-}
-
-func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*float64)(ptr)) = iter.ReadFloat64()
-	}
-}
-
-func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteFloat64(*((*float64)(ptr)))
-}
-
-func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*float64)(ptr)) == 0
-}
-
-type boolCodec struct {
-}
-
-func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if !iter.ReadNil() {
-		*((*bool)(ptr)) = iter.ReadBool()
-	}
-}
-
-func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteBool(*((*bool)(ptr)))
-}
-
-func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
-	return !(*((*bool)(ptr)))
-}
-
-type base64Codec struct {
-	sliceType    *reflect2.UnsafeSliceType
-	sliceDecoder ValDecoder
-}
-
-func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if iter.ReadNil() {
-		codec.sliceType.UnsafeSetNil(ptr)
-		return
-	}
-	switch iter.WhatIsNext() {
-	case StringValue:
-		src := iter.ReadString()
-		dst, err := base64.StdEncoding.DecodeString(src)
-		if err != nil {
-			iter.ReportError("decode base64", err.Error())
-		} else {
-			codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst))
-		}
-	case ArrayValue:
-		codec.sliceDecoder.Decode(ptr, iter)
-	default:
-		iter.ReportError("base64Codec", "invalid input")
-	}
-}
-
-func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
-	src := *((*[]byte)(ptr))
-	if len(src) == 0 {
-		stream.WriteNil()
-		return
-	}
-	encoding := base64.StdEncoding
-	stream.writeByte('"')
-	size := encoding.EncodedLen(len(src))
-	buf := make([]byte, size)
-	encoding.Encode(buf, src)
-	stream.buf = append(stream.buf, buf...)
-	stream.writeByte('"')
-}
-
-func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
-	return len(*((*[]byte)(ptr))) == 0
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go
deleted file mode 100644
index 43ec71d6d..000000000
--- a/vendor/github.com/json-iterator/go/reflect_optional.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package jsoniter
-
-import (
-	"github.com/modern-go/reflect2"
-	"reflect"
-	"unsafe"
-)
-
-func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder {
-	ptrType := typ.(*reflect2.UnsafePtrType)
-	elemType := ptrType.Elem()
-	decoder := decoderOfType(ctx, elemType)
-	if ctx.prefix == "" && elemType.Kind() == reflect.Ptr {
-		return &dereferenceDecoder{elemType, decoder}
-	}
-	return &OptionalDecoder{elemType, decoder}
-}
-
-func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder {
-	ptrType := typ.(*reflect2.UnsafePtrType)
-	elemType := ptrType.Elem()
-	elemEncoder := encoderOfType(ctx, elemType)
-	encoder := &OptionalEncoder{elemEncoder}
-	return encoder
-}
-
-type OptionalDecoder struct {
-	ValueType    reflect2.Type
-	ValueDecoder ValDecoder
-}
-
-func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if iter.ReadNil() {
-		*((*unsafe.Pointer)(ptr)) = nil
-	} else {
-		if *((*unsafe.Pointer)(ptr)) == nil {
-			//pointer to null, we have to allocate memory to hold the value
-			newPtr := decoder.ValueType.UnsafeNew()
-			decoder.ValueDecoder.Decode(newPtr, iter)
-			*((*unsafe.Pointer)(ptr)) = newPtr
-		} else {
-			//reuse existing instance
-			decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
-		}
-	}
-}
-
-type dereferenceDecoder struct {
-	// only to deference a pointer
-	valueType    reflect2.Type
-	valueDecoder ValDecoder
-}
-
-func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	if *((*unsafe.Pointer)(ptr)) == nil {
-		//pointer to null, we have to allocate memory to hold the value
-		newPtr := decoder.valueType.UnsafeNew()
-		decoder.valueDecoder.Decode(newPtr, iter)
-		*((*unsafe.Pointer)(ptr)) = newPtr
-	} else {
-		//reuse existing instance
-		decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
-	}
-}
-
-type OptionalEncoder struct {
-	ValueEncoder ValEncoder
-}
-
-func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	if *((*unsafe.Pointer)(ptr)) == nil {
-		stream.WriteNil()
-	} else {
-		encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
-	}
-}
-
-func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return *((*unsafe.Pointer)(ptr)) == nil
-}
-
-type dereferenceEncoder struct {
-	ValueEncoder ValEncoder
-}
-
-func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	if *((*unsafe.Pointer)(ptr)) == nil {
-		stream.WriteNil()
-	} else {
-		encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
-	}
-}
-
-func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	dePtr := *((*unsafe.Pointer)(ptr))
-	if dePtr == nil {
-		return true
-	}
-	return encoder.ValueEncoder.IsEmpty(dePtr)
-}
-
-func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
-	deReferenced := *((*unsafe.Pointer)(ptr))
-	if deReferenced == nil {
-		return true
-	}
-	isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil)
-	if !converted {
-		return false
-	}
-	fieldPtr := unsafe.Pointer(deReferenced)
-	return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
-}
-
-type referenceEncoder struct {
-	encoder ValEncoder
-}
-
-func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
-}
-
-func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
-}
-
-type referenceDecoder struct {
-	decoder ValDecoder
-}
-
-func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	decoder.decoder.Decode(unsafe.Pointer(&ptr), iter)
-}
diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go
deleted file mode 100644
index 9441d79df..000000000
--- a/vendor/github.com/json-iterator/go/reflect_slice.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package jsoniter
-
-import (
-	"fmt"
-	"github.com/modern-go/reflect2"
-	"io"
-	"unsafe"
-)
-
-func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder {
-	sliceType := typ.(*reflect2.UnsafeSliceType)
-	decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
-	return &sliceDecoder{sliceType, decoder}
-}
-
-func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder {
-	sliceType := typ.(*reflect2.UnsafeSliceType)
-	encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
-	return &sliceEncoder{sliceType, encoder}
-}
-
-type sliceEncoder struct {
-	sliceType   *reflect2.UnsafeSliceType
-	elemEncoder ValEncoder
-}
-
-func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
-	if encoder.sliceType.UnsafeIsNil(ptr) {
-		stream.WriteNil()
-		return
-	}
-	length := encoder.sliceType.UnsafeLengthOf(ptr)
-	if length == 0 {
-		stream.WriteEmptyArray()
-		return
-	}
-	stream.WriteArrayStart()
-	encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream)
-	for i := 1; i < length; i++ {
-		stream.WriteMore()
-		elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i)
-		encoder.elemEncoder.Encode(elemPtr, stream)
-	}
-	stream.WriteArrayEnd()
-	if stream.Error != nil && stream.Error != io.EOF {
-		stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
-	}
-}
-
-func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
-	return encoder.sliceType.UnsafeLengthOf(ptr) == 0
-}
-
-type sliceDecoder struct {
-	sliceType   *reflect2.UnsafeSliceType
-	elemDecoder ValDecoder
-}
-
-func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	decoder.doDecode(ptr, iter)
-	if iter.Error != nil && iter.Error != io.EOF {
-		iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
-	}
-}
-
-func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
-	c := iter.nextToken()
-	sliceType := decoder.sliceType
-	if c == 'n' {
-		iter.skipThreeBytes('u', 'l', 'l')
-		sliceType.UnsafeSetNil(ptr)
-		return
-	}
-	if c != '[' {
-		iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c}))
-		return
-	}
-	c = iter.nextToken()
-	if c == ']' {
-		sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0))
-		return
-	}
-	iter.unreadByte()
-	sliceType.UnsafeGrow(ptr, 1)
-	elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
-	decoder.elemDecoder.Decode(elemPtr, iter)
-	length := 1
-	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
-		idx := length
-		length += 1
-		sliceType.UnsafeGrow(ptr, length)
-		elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
-		decoder.elemDecoder.Decode(elemPtr, iter)
-	}
-	if c != ']' {
-		iter.ReportError("decode slice", "expect ], but found "+string([]byte{c}))
-		return
-	}
-}
diff --git a/vendor/github.com/json-iterator/go/skip_tests/array/skip_test.go b/vendor/github.com/json-iterator/go/skip_tests/array/skip_test.go
new file mode 120000
index 000000000..0334f5793
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/array/skip_test.go
@@ -0,0 +1 @@
+../number/skip_test.go
\ No newline at end of file
diff --git a/vendor/github.com/json-iterator/go/skip_tests/object/skip_test.go b/vendor/github.com/json-iterator/go/skip_tests/object/skip_test.go
new file mode 120000
index 000000000..0334f5793
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/object/skip_test.go
@@ -0,0 +1 @@
+../number/skip_test.go
\ No newline at end of file
diff --git a/vendor/github.com/json-iterator/go/skip_tests/string/skip_test.go b/vendor/github.com/json-iterator/go/skip_tests/string/skip_test.go
new file mode 120000
index 000000000..0334f5793
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/string/skip_test.go
@@ -0,0 +1 @@
+../number/skip_test.go
\ No newline at end of file
diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go
deleted file mode 100644
index d1059ee4c..000000000
--- a/vendor/github.com/json-iterator/go/stream_int.go
+++ /dev/null
@@ -1,190 +0,0 @@
-package jsoniter
-
-var digits []uint32
-
-func init() {
-	digits = make([]uint32, 1000)
-	for i := uint32(0); i < 1000; i++ {
-		digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
-		if i < 10 {
-			digits[i] += 2 << 24
-		} else if i < 100 {
-			digits[i] += 1 << 24
-		}
-	}
-}
-
-func writeFirstBuf(space []byte, v uint32) []byte {
-	start := v >> 24
-	if start == 0 {
-		space = append(space, byte(v>>16), byte(v>>8))
-	} else if start == 1 {
-		space = append(space, byte(v>>8))
-	}
-	space = append(space, byte(v))
-	return space
-}
-
-func writeBuf(buf []byte, v uint32) []byte {
-	return append(buf, byte(v>>16), byte(v>>8), byte(v))
-}
-
-// WriteUint8 write uint8 to stream
-func (stream *Stream) WriteUint8(val uint8) {
-	stream.buf = writeFirstBuf(stream.buf, digits[val])
-}
-
-// WriteInt8 write int8 to stream
-func (stream *Stream) WriteInt8(nval int8) {
-	var val uint8
-	if nval < 0 {
-		val = uint8(-nval)
-		stream.buf = append(stream.buf, '-')
-	} else {
-		val = uint8(nval)
-	}
-	stream.buf = writeFirstBuf(stream.buf, digits[val])
-}
-
-// WriteUint16 write uint16 to stream
-func (stream *Stream) WriteUint16(val uint16) {
-	q1 := val / 1000
-	if q1 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[val])
-		return
-	}
-	r1 := val - q1*1000
-	stream.buf = writeFirstBuf(stream.buf, digits[q1])
-	stream.buf = writeBuf(stream.buf, digits[r1])
-	return
-}
-
-// WriteInt16 write int16 to stream
-func (stream *Stream) WriteInt16(nval int16) {
-	var val uint16
-	if nval < 0 {
-		val = uint16(-nval)
-		stream.buf = append(stream.buf, '-')
-	} else {
-		val = uint16(nval)
-	}
-	stream.WriteUint16(val)
-}
-
-// WriteUint32 write uint32 to stream
-func (stream *Stream) WriteUint32(val uint32) {
-	q1 := val / 1000
-	if q1 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[val])
-		return
-	}
-	r1 := val - q1*1000
-	q2 := q1 / 1000
-	if q2 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[q1])
-		stream.buf = writeBuf(stream.buf, digits[r1])
-		return
-	}
-	r2 := q1 - q2*1000
-	q3 := q2 / 1000
-	if q3 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[q2])
-	} else {
-		r3 := q2 - q3*1000
-		stream.buf = append(stream.buf, byte(q3+'0'))
-		stream.buf = writeBuf(stream.buf, digits[r3])
-	}
-	stream.buf = writeBuf(stream.buf, digits[r2])
-	stream.buf = writeBuf(stream.buf, digits[r1])
-}
-
-// WriteInt32 write int32 to stream
-func (stream *Stream) WriteInt32(nval int32) {
-	var val uint32
-	if nval < 0 {
-		val = uint32(-nval)
-		stream.buf = append(stream.buf, '-')
-	} else {
-		val = uint32(nval)
-	}
-	stream.WriteUint32(val)
-}
-
-// WriteUint64 write uint64 to stream
-func (stream *Stream) WriteUint64(val uint64) {
-	q1 := val / 1000
-	if q1 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[val])
-		return
-	}
-	r1 := val - q1*1000
-	q2 := q1 / 1000
-	if q2 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[q1])
-		stream.buf = writeBuf(stream.buf, digits[r1])
-		return
-	}
-	r2 := q1 - q2*1000
-	q3 := q2 / 1000
-	if q3 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[q2])
-		stream.buf = writeBuf(stream.buf, digits[r2])
-		stream.buf = writeBuf(stream.buf, digits[r1])
-		return
-	}
-	r3 := q2 - q3*1000
-	q4 := q3 / 1000
-	if q4 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[q3])
-		stream.buf = writeBuf(stream.buf, digits[r3])
-		stream.buf = writeBuf(stream.buf, digits[r2])
-		stream.buf = writeBuf(stream.buf, digits[r1])
-		return
-	}
-	r4 := q3 - q4*1000
-	q5 := q4 / 1000
-	if q5 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[q4])
-		stream.buf = writeBuf(stream.buf, digits[r4])
-		stream.buf = writeBuf(stream.buf, digits[r3])
-		stream.buf = writeBuf(stream.buf, digits[r2])
-		stream.buf = writeBuf(stream.buf, digits[r1])
-		return
-	}
-	r5 := q4 - q5*1000
-	q6 := q5 / 1000
-	if q6 == 0 {
-		stream.buf = writeFirstBuf(stream.buf, digits[q5])
-	} else {
-		stream.buf = writeFirstBuf(stream.buf, digits[q6])
-		r6 := q5 - q6*1000
-		stream.buf = writeBuf(stream.buf, digits[r6])
-	}
-	stream.buf = writeBuf(stream.buf, digits[r5])
-	stream.buf = writeBuf(stream.buf, digits[r4])
-	stream.buf = writeBuf(stream.buf, digits[r3])
-	stream.buf = writeBuf(stream.buf, digits[r2])
-	stream.buf = writeBuf(stream.buf, digits[r1])
-}
-
-// WriteInt64 write int64 to stream
-func (stream *Stream) WriteInt64(nval int64) {
-	var val uint64
-	if nval < 0 {
-		val = uint64(-nval)
-		stream.buf = append(stream.buf, '-')
-	} else {
-		val = uint64(nval)
-	}
-	stream.WriteUint64(val)
-}
-
-// WriteInt write int to stream
-func (stream *Stream) WriteInt(val int) {
-	stream.WriteInt64(int64(val))
-}
-
-// WriteUint write uint to stream
-func (stream *Stream) WriteUint(val uint) {
-	stream.WriteUint64(uint64(val))
-}
diff --git a/vendor/github.com/json-iterator/go/test.sh b/vendor/github.com/json-iterator/go/test.sh
new file mode 100755
index 000000000..466f1141a
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/test.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+set -e
+echo "" > coverage.txt
+
+for d in $(go list ./... | grep -v vendor); do
+    go test -coverprofile=profile.out $d
+    if [ -f profile.out ]; then
+        cat profile.out >> coverage.txt
+        rm profile.out
+    fi
+done
diff --git a/vendor/github.com/kardianos/osext/README.md b/vendor/github.com/kardianos/osext/README.md
new file mode 100644
index 000000000..15cbc3d95
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/README.md
@@ -0,0 +1,21 @@
+### Extensions to the "os" package.
+
+[![GoDoc](https://godoc.org/github.com/kardianos/osext?status.svg)](https://godoc.org/github.com/kardianos/osext)
+
+## Find the current Executable and ExecutableFolder.
+
+As of go1.8 the Executable function may be found in `os`. The Executable function
+in the std lib `os` package is used if available.
+
+There is sometimes utility in finding the current executable file
+that is running. This can be used for upgrading the current executable
+or finding resources located relative to the executable file. Both
+working directory and the os.Args[0] value are arbitrary and cannot
+be relied on; os.Args[0] can be "faked".
+
+Multi-platform and supports:
+ * Linux
+ * OS X
+ * Windows
+ * Plan 9
+ * BSDs.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
new file mode 100644
index 000000000..949b77e30
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
@@ -0,0 +1,40 @@
+# Windows Terminal Sequences
+
+This library allow for enabling Windows terminal color support for Go.
+
+See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details.
+
+## Usage
+
+```go
+import (
+	"syscall"
+	
+	sequences "github.com/konsorten/go-windows-terminal-sequences"
+)
+
+func main() {
+	sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true)
+}
+
+```
+
+## Authors
+
+The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de).
+
+We thank all the authors who provided code to this library:
+
+* Felix Kollmann
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
new file mode 100644
index 000000000..716c61312
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
@@ -0,0 +1 @@
+module github.com/konsorten/go-windows-terminal-sequences
diff --git a/vendor/github.com/kr/binarydist/.gitignore b/vendor/github.com/kr/binarydist/.gitignore
new file mode 100644
index 000000000..653f16014
--- /dev/null
+++ b/vendor/github.com/kr/binarydist/.gitignore
@@ -0,0 +1 @@
+test.*
diff --git a/vendor/github.com/kr/binarydist/Readme.md b/vendor/github.com/kr/binarydist/Readme.md
new file mode 100644
index 000000000..dadc3683d
--- /dev/null
+++ b/vendor/github.com/kr/binarydist/Readme.md
@@ -0,0 +1,7 @@
+# binarydist
+
+Package binarydist implements binary diff and patch as described on
+<http://www.daemonology.net/bsdiff/>. It reads and writes files
+compatible with the tools there.
+
+Documentation at <http://go.pkgdoc.org/github.com/kr/binarydist>.
diff --git a/vendor/github.com/kr/binarydist/go.mod b/vendor/github.com/kr/binarydist/go.mod
new file mode 100644
index 000000000..ecdfe3ea1
--- /dev/null
+++ b/vendor/github.com/kr/binarydist/go.mod
@@ -0,0 +1 @@
+module "github.com/kr/binarydist"
diff --git a/vendor/github.com/kr/fs/Readme b/vendor/github.com/kr/fs/Readme
new file mode 100644
index 000000000..c95e13fc8
--- /dev/null
+++ b/vendor/github.com/kr/fs/Readme
@@ -0,0 +1,3 @@
+Filesystem Package
+
+http://godoc.org/github.com/kr/fs
diff --git a/vendor/github.com/kr/fs/go.mod b/vendor/github.com/kr/fs/go.mod
new file mode 100644
index 000000000..7c206e04c
--- /dev/null
+++ b/vendor/github.com/kr/fs/go.mod
@@ -0,0 +1 @@
+module "github.com/kr/fs"
diff --git a/vendor/github.com/mattn/go-isatty/.travis.yml b/vendor/github.com/mattn/go-isatty/.travis.yml
new file mode 100644
index 000000000..b9f8b239c
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+  - tip
+
+before_install:
+  - go get github.com/mattn/goveralls
+  - go get golang.org/x/tools/cmd/cover
+script:
+  - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5
diff --git a/vendor/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md
new file mode 100644
index 000000000..1e69004bb
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/README.md
@@ -0,0 +1,50 @@
+# go-isatty
+
+[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)
+[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty)
+[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)
+[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty)
+
+isatty for golang
+
+## Usage
+
+```go
+package main
+
+import (
+	"fmt"
+	"github.com/mattn/go-isatty"
+	"os"
+)
+
+func main() {
+	if isatty.IsTerminal(os.Stdout.Fd()) {
+		fmt.Println("Is Terminal")
+	} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
+		fmt.Println("Is Cygwin/MSYS2 Terminal")
+	} else {
+		fmt.Println("Is Not Terminal")
+	}
+}
+```
+
+## Installation
+
+```
+$ go get github.com/mattn/go-isatty
+```
+
+## License
+
+MIT
+
+## Author
+
+Yasuhiro Matsumoto (a.k.a mattn)
+
+## Thanks
+
+* k-takata: base idea for IsCygwinTerminal
+
+    https://github.com/k-takata/go-iscygpty
diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux.go b/vendor/github.com/mattn/go-isatty/isatty_linux.go
index 7384cf991..9d24bac1d 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_linux.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_linux.go
@@ -1,5 +1,5 @@
 // +build linux
-// +build !appengine,!ppc64,!ppc64le
+// +build !appengine
 
 package isatty
 
diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go b/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go
deleted file mode 100644
index 44e5d2130..000000000
--- a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build linux
-// +build ppc64 ppc64le
-
-package isatty
-
-import (
-	"unsafe"
-
-	syscall "golang.org/x/sys/unix"
-)
-
-const ioctlReadTermios = syscall.TCGETS
-
-// IsTerminal return true if the file descriptor is terminal.
-func IsTerminal(fd uintptr) bool {
-	var termios syscall.Termios
-	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
-	return err == 0
-}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go
index 9d8b4a599..ff4de3d9a 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_others.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_others.go
@@ -3,7 +3,7 @@
 
 package isatty
 
-// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
 // terminal. This is also always false on this environment.
 func IsCygwinTerminal(fd uintptr) bool {
 	return false
diff --git a/vendor/github.com/mattn/go-shellwords/.travis.yml b/vendor/github.com/mattn/go-shellwords/.travis.yml
new file mode 100644
index 000000000..16d1430aa
--- /dev/null
+++ b/vendor/github.com/mattn/go-shellwords/.travis.yml
@@ -0,0 +1,8 @@
+language: go
+go:
+  - tip
+before_install:
+  - go get github.com/mattn/goveralls
+  - go get golang.org/x/tools/cmd/cover
+script:
+    - $HOME/gopath/bin/goveralls -repotoken 2FMhp57u8LcstKL9B190fLTcEnBtAAiEL
diff --git a/vendor/github.com/mattn/go-shellwords/README.md b/vendor/github.com/mattn/go-shellwords/README.md
new file mode 100644
index 000000000..b1d235c78
--- /dev/null
+++ b/vendor/github.com/mattn/go-shellwords/README.md
@@ -0,0 +1,47 @@
+# go-shellwords
+
+[![Coverage Status](https://coveralls.io/repos/mattn/go-shellwords/badge.png?branch=master)](https://coveralls.io/r/mattn/go-shellwords?branch=master)
+[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords)
+
+Parse line as shell words.
+
+## Usage
+
+```go
+args, err := shellwords.Parse("./foo --bar=baz")
+// args should be ["./foo", "--bar=baz"]
+```
+
+```go
+os.Setenv("FOO", "bar")
+p := shellwords.NewParser()
+p.ParseEnv = true
+args, err := p.Parse("./foo $FOO")
+// args should be ["./foo", "bar"]
+```
+
+```go
+p := shellwords.NewParser()
+p.ParseBacktick = true
+args, err := p.Parse("./foo `echo $SHELL`")
+// args should be ["./foo", "/bin/bash"]
+```
+
+```go
+shellwords.ParseBacktick = true
+p := shellwords.NewParser()
+args, err := p.Parse("./foo `echo $SHELL`")
+// args should be ["./foo", "/bin/bash"]
+```
+
+# Thanks
+
+This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine).
+
+# License
+
+under the MIT License: http://mattn.mit-license.org/2017
+
+# Author
+
+Yasuhiro Matsumoto (a.k.a mattn)
diff --git a/vendor/github.com/miekg/dns/.codecov.yml b/vendor/github.com/miekg/dns/.codecov.yml
new file mode 100644
index 000000000..f91e5c1fe
--- /dev/null
+++ b/vendor/github.com/miekg/dns/.codecov.yml
@@ -0,0 +1,8 @@
+coverage:
+  status:
+    project:
+      default:
+        target: 40%
+        threshold: null
+    patch: false
+    changes: false
diff --git a/vendor/github.com/miekg/dns/.gitignore b/vendor/github.com/miekg/dns/.gitignore
new file mode 100644
index 000000000..776cd950c
--- /dev/null
+++ b/vendor/github.com/miekg/dns/.gitignore
@@ -0,0 +1,4 @@
+*.6
+tags
+test.out
+a.out
diff --git a/vendor/github.com/miekg/dns/.travis.yml b/vendor/github.com/miekg/dns/.travis.yml
new file mode 100644
index 000000000..18259374e
--- /dev/null
+++ b/vendor/github.com/miekg/dns/.travis.yml
@@ -0,0 +1,18 @@
+language: go
+sudo: false
+
+go:
+  - 1.10.x
+  - 1.11.x
+  - tip
+
+before_install:
+  # don't use the miekg/dns when testing forks
+  - mkdir -p $GOPATH/src/github.com/miekg
+  - ln -s $TRAVIS_BUILD_DIR $GOPATH/src/github.com/miekg/ || true
+
+script:
+  - go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./...
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/miekg/dns/Gopkg.lock b/vendor/github.com/miekg/dns/Gopkg.lock
new file mode 100644
index 000000000..686632207
--- /dev/null
+++ b/vendor/github.com/miekg/dns/Gopkg.lock
@@ -0,0 +1,57 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+  branch = "master"
+  digest = "1:6914c49eed986dfb8dffb33516fa129c49929d4d873f41e073c83c11c372b870"
+  name = "golang.org/x/crypto"
+  packages = [
+    "ed25519",
+    "ed25519/internal/edwards25519",
+  ]
+  pruneopts = ""
+  revision = "e3636079e1a4c1f337f212cc5cd2aca108f6c900"
+
+[[projects]]
+  branch = "master"
+  digest = "1:08e41d63f8dac84d83797368b56cf0b339e42d0224e5e56668963c28aec95685"
+  name = "golang.org/x/net"
+  packages = [
+    "bpf",
+    "context",
+    "internal/iana",
+    "internal/socket",
+    "ipv4",
+    "ipv6",
+  ]
+  pruneopts = ""
+  revision = "4dfa2610cdf3b287375bbba5b8f2a14d3b01d8de"
+
+[[projects]]
+  branch = "master"
+  digest = "1:b2ea75de0ccb2db2ac79356407f8a4cd8f798fe15d41b381c00abf3ae8e55ed1"
+  name = "golang.org/x/sync"
+  packages = ["errgroup"]
+  pruneopts = ""
+  revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
+
+[[projects]]
+  branch = "master"
+  digest = "1:149a432fabebb8221a80f77731b1cd63597197ded4f14af606ebe3a0959004ec"
+  name = "golang.org/x/sys"
+  packages = ["unix"]
+  pruneopts = ""
+  revision = "e4b3c5e9061176387e7cea65e4dc5853801f3fb7"
+
+[solve-meta]
+  analyzer-name = "dep"
+  analyzer-version = 1
+  input-imports = [
+    "golang.org/x/crypto/ed25519",
+    "golang.org/x/net/ipv4",
+    "golang.org/x/net/ipv6",
+    "golang.org/x/sync/errgroup",
+    "golang.org/x/sys/unix",
+  ]
+  solver-name = "gps-cdcl"
+  solver-version = 1
diff --git a/vendor/github.com/miekg/dns/Gopkg.toml b/vendor/github.com/miekg/dns/Gopkg.toml
new file mode 100644
index 000000000..85e6ff31b
--- /dev/null
+++ b/vendor/github.com/miekg/dns/Gopkg.toml
@@ -0,0 +1,38 @@
+
+# Gopkg.toml example
+#
+# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
+# for detailed Gopkg.toml documentation.
+#
+# required = ["github.com/user/thing/cmd/thing"]
+# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
+#
+# [[constraint]]
+#   name = "github.com/user/project"
+#   version = "1.0.0"
+#
+# [[constraint]]
+#   name = "github.com/user/project2"
+#   branch = "dev"
+#   source = "github.com/myfork/project2"
+#
+# [[override]]
+#  name = "github.com/x/y"
+#  version = "2.4.0"
+
+
+[[constraint]]
+  branch = "master"
+  name = "golang.org/x/crypto"
+
+[[constraint]]
+  branch = "master"
+  name = "golang.org/x/net"
+
+[[constraint]]
+  branch = "master"
+  name = "golang.org/x/sys"
+
+[[constraint]]
+  branch = "master"
+  name = "golang.org/x/sync"
diff --git a/vendor/github.com/miekg/dns/Makefile.fuzz b/vendor/github.com/miekg/dns/Makefile.fuzz
new file mode 100644
index 000000000..dc158c4ac
--- /dev/null
+++ b/vendor/github.com/miekg/dns/Makefile.fuzz
@@ -0,0 +1,33 @@
+# Makefile for fuzzing
+#
+# Use go-fuzz and needs the tools installed.
+# See https://blog.cloudflare.com/dns-parser-meet-go-fuzzer/
+#
+# Installing go-fuzz:
+# $ make -f Makefile.fuzz get
+# Installs:
+# * github.com/dvyukov/go-fuzz/go-fuzz
+# * get github.com/dvyukov/go-fuzz/go-fuzz-build
+
+all: build
+
+.PHONY: build
+build:
+	go-fuzz-build -tags fuzz github.com/miekg/dns
+
+.PHONY: build-newrr
+build-newrr:
+	go-fuzz-build -func FuzzNewRR -tags fuzz github.com/miekg/dns
+
+.PHONY: fuzz
+fuzz:
+	go-fuzz -bin=dns-fuzz.zip -workdir=fuzz
+
+.PHONY: get
+get:
+	go get github.com/dvyukov/go-fuzz/go-fuzz
+	go get github.com/dvyukov/go-fuzz/go-fuzz-build
+
+.PHONY: clean
+clean:
+	rm *-fuzz.zip
diff --git a/vendor/github.com/miekg/dns/Makefile.release b/vendor/github.com/miekg/dns/Makefile.release
new file mode 100644
index 000000000..8fb748e8a
--- /dev/null
+++ b/vendor/github.com/miekg/dns/Makefile.release
@@ -0,0 +1,52 @@
+# Makefile for releasing.
+#
+# The release is controlled from version.go. The version found there is
+# used to tag the git repo, we're not building any artifects so there is nothing
+# to upload to github.
+#
+# * Up the version in version.go
+# * Run: make -f Makefile.release release
+#   * will *commit* your change with 'Release $VERSION'
+#   * push to github
+#
+
+define GO
+//+build ignore
+
+package main
+
+import (
+	"fmt"
+
+	"github.com/miekg/dns"
+)
+
+func main() {
+	fmt.Println(dns.Version.String())
+}
+endef
+
+$(file > version_release.go,$(GO))
+VERSION:=$(shell go run version_release.go)
+TAG="v$(VERSION)"
+
+all:
+	@echo Use the \'release\' target to start a release $(VERSION)
+	rm -f version_release.go
+
+.PHONY: release
+release: commit push
+	@echo Released $(VERSION)
+	rm -f version_release.go
+
+.PHONY: commit
+commit:
+	@echo Committing release $(VERSION)
+	git commit -am"Release $(VERSION)"
+	git tag $(TAG)
+
+.PHONY: push
+push:
+	@echo Pushing release $(VERSION) to master
+	git push --tags
+	git push
diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md
new file mode 100644
index 000000000..7f1aaa5de
--- /dev/null
+++ b/vendor/github.com/miekg/dns/README.md
@@ -0,0 +1,172 @@
+[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)
+[![Code Coverage](https://img.shields.io/codecov/c/github/miekg/dns/master.svg)](https://codecov.io/github/miekg/dns?branch=master)
+[![Go Report Card](https://goreportcard.com/badge/github.com/miekg/dns)](https://goreportcard.com/report/miekg/dns)
+[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns)
+
+# Alternative (more granular) approach to a DNS library
+
+> Less is more.
+
+Complete and usable DNS library. All widely used Resource Records are supported, including the
+DNSSEC types. It follows a lean and mean philosophy. If there is stuff you should know as a DNS
+programmer there isn't a convenience function for it. Server side and client side programming is
+supported, i.e. you can build servers and resolvers with it.
+
+We try to keep the "master" branch as sane as possible and at the bleeding edge of standards,
+avoiding breaking changes wherever reasonable. We support the last two versions of Go.
+
+# Goals
+
+* KISS;
+* Fast;
+* Small API. If it's easy to code in Go, don't make a function for it.
+
+# Users
+
+A not-so-up-to-date-list-that-may-be-actually-current:
+
+* https://github.com/coredns/coredns
+* https://cloudflare.com
+* https://github.com/abh/geodns
+* http://www.statdns.com/
+* http://www.dnsinspect.com/
+* https://github.com/chuangbo/jianbing-dictionary-dns
+* http://www.dns-lg.com/
+* https://github.com/fcambus/rrda
+* https://github.com/kenshinx/godns
+* https://github.com/skynetservices/skydns
+* https://github.com/hashicorp/consul
+* https://github.com/DevelopersPL/godnsagent
+* https://github.com/duedil-ltd/discodns
+* https://github.com/StalkR/dns-reverse-proxy
+* https://github.com/tianon/rawdns
+* https://mesosphere.github.io/mesos-dns/
+* https://pulse.turbobytes.com/
+* https://play.google.com/store/apps/details?id=com.turbobytes.dig
+* https://github.com/fcambus/statzone
+* https://github.com/benschw/dns-clb-go
+* https://github.com/corny/dnscheck for http://public-dns.info/
+* https://namesmith.io
+* https://github.com/miekg/unbound
+* https://github.com/miekg/exdns
+* https://dnslookup.org
+* https://github.com/looterz/grimd
+* https://github.com/phamhongviet/serf-dns
+* https://github.com/mehrdadrad/mylg
+* https://github.com/bamarni/dockness
+* https://github.com/fffaraz/microdns
+* http://kelda.io
+* https://github.com/ipdcode/hades (JD.COM)
+* https://github.com/StackExchange/dnscontrol/
+* https://www.dnsperf.com/
+* https://dnssectest.net/
+* https://dns.apebits.com
+* https://github.com/oif/apex
+* https://github.com/jedisct1/dnscrypt-proxy
+* https://github.com/jedisct1/rpdns
+* https://github.com/xor-gate/sshfp
+* https://github.com/rs/dnstrace
+* https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss))
+* https://github.com/semihalev/sdns
+
+Send pull request if you want to be listed here.
+
+# Features
+
+* UDP/TCP queries, IPv4 and IPv6;
+* RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported;
+* Fast:
+    * Reply speed around ~ 80K qps (faster hardware results in more qps);
+    * Parsing RRs ~ 100K RR/s, that's 5M records in about 50 seconds;
+* Server side programming (mimicking the net/http package);
+* Client side programming;
+* DNSSEC: signing, validating and key generation for DSA, RSA, ECDSA and Ed25519;
+* EDNS0, NSID, Cookies;
+* AXFR/IXFR;
+* TSIG, SIG(0);
+* DNS over TLS: optional encrypted connection between client and server;
+* DNS name compression;
+* Depends only on the standard library.
+
+Have fun!
+
+Miek Gieben  -  2010-2012  -  <miek@miek.nl>
+
+# Building
+
+Building is done with the `go` tool. If you have setup your GOPATH correctly, the following should
+work:
+
+    go get github.com/miekg/dns
+    go build github.com/miekg/dns
+
+## Examples
+
+A short "how to use the API" is at the beginning of doc.go (this also will show
+when you call `godoc github.com/miekg/dns`).
+
+Example programs can be found in the `github.com/miekg/exdns` repository.
+
+## Supported RFCs
+
+*all of them*
+
+* 103{4,5} - DNS standard
+* 1348 - NSAP record (removed the record)
+* 1982 - Serial Arithmetic
+* 1876 - LOC record
+* 1995 - IXFR
+* 1996 - DNS notify
+* 2136 - DNS Update (dynamic updates)
+* 2181 - RRset definition - there is no RRset type though, just []RR
+* 2537 - RSAMD5 DNS keys
+* 2065 - DNSSEC (updated in later RFCs)
+* 2671 - EDNS record
+* 2782 - SRV record
+* 2845 - TSIG record
+* 2915 - NAPTR record
+* 2929 - DNS IANA Considerations
+* 3110 - RSASHA1 DNS keys
+* 3225 - DO bit (DNSSEC OK)
+* 340{1,2,3} - NAPTR record
+* 3445 - Limiting the scope of (DNS)KEY
+* 3597 - Unknown RRs
+* 403{3,4,5} - DNSSEC + validation functions
+* 4255 - SSHFP record
+* 4343 - Case insensitivity
+* 4408 - SPF record
+* 4509 - SHA256 Hash in DS
+* 4592 - Wildcards in the DNS
+* 4635 - HMAC SHA TSIG
+* 4701 - DHCID
+* 4892 - id.server
+* 5001 - NSID
+* 5155 - NSEC3 record
+* 5205 - HIP record
+* 5702 - SHA2 in the DNS
+* 5936 - AXFR
+* 5966 - TCP implementation recommendations
+* 6605 - ECDSA
+* 6725 - IANA Registry Update
+* 6742 - ILNP DNS
+* 6840 - Clarifications and Implementation Notes for DNS Security
+* 6844 - CAA record
+* 6891 - EDNS0 update
+* 6895 - DNS IANA considerations
+* 6975 - Algorithm Understanding in DNSSEC
+* 7043 - EUI48/EUI64 records
+* 7314 - DNS (EDNS) EXPIRE Option
+* 7477 - CSYNC RR
+* 7828 - edns-tcp-keepalive EDNS0 Option
+* 7553 - URI record
+* 7858 - DNS over TLS: Initiation and Performance Considerations
+* 7871 - EDNS0 Client Subnet
+* 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies)
+* 8080 - EdDSA for DNSSEC
+
+## Loosely based upon
+
+* `ldns`
+* `NSD`
+* `Net::DNS`
+* `GRONG`
diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go
index 63ced2bd0..770a946cd 100644
--- a/vendor/github.com/miekg/dns/client.go
+++ b/vendor/github.com/miekg/dns/client.go
@@ -7,11 +7,8 @@ import (
 	"context"
 	"crypto/tls"
 	"encoding/binary"
-	"fmt"
 	"io"
-	"io/ioutil"
 	"net"
-	"net/http"
 	"strings"
 	"time"
 )
@@ -19,8 +16,6 @@ import (
 const (
 	dnsTimeout     time.Duration = 2 * time.Second
 	tcpIdleTimeout time.Duration = 8 * time.Second
-
-	dohMimeType = "application/dns-message"
 )
 
 // A Conn represents a connection to a DNS server.
@@ -44,7 +39,6 @@ type Client struct {
 	DialTimeout    time.Duration     // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
 	ReadTimeout    time.Duration     // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
 	WriteTimeout   time.Duration     // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
-	HTTPClient     *http.Client      // The http.Client to use for DNS-over-HTTPS
 	TsigSecret     map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
 	SingleInflight bool              // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
 	group          singleflight
@@ -132,11 +126,6 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
 // attribute appropriately
 func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
 	if !c.SingleInflight {
-		if c.Net == "https" {
-			// TODO(tmthrgd): pipe timeouts into exchangeDOH
-			return c.exchangeDOH(context.TODO(), m, address)
-		}
-
 		return c.exchange(m, address)
 	}
 
@@ -149,11 +138,6 @@ func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, er
 		cl = cl1
 	}
 	r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
-		if c.Net == "https" {
-			// TODO(tmthrgd): pipe timeouts into exchangeDOH
-			return c.exchangeDOH(context.TODO(), m, address)
-		}
-
 		return c.exchange(m, address)
 	})
 	if r != nil && shared {
@@ -199,67 +183,6 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
 	return r, rtt, err
 }
 
-func (c *Client) exchangeDOH(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
-	p, err := m.Pack()
-	if err != nil {
-		return nil, 0, err
-	}
-
-	req, err := http.NewRequest(http.MethodPost, a, bytes.NewReader(p))
-	if err != nil {
-		return nil, 0, err
-	}
-
-	req.Header.Set("Content-Type", dohMimeType)
-	req.Header.Set("Accept", dohMimeType)
-
-	hc := http.DefaultClient
-	if c.HTTPClient != nil {
-		hc = c.HTTPClient
-	}
-
-	if ctx != context.Background() && ctx != context.TODO() {
-		req = req.WithContext(ctx)
-	}
-
-	t := time.Now()
-
-	resp, err := hc.Do(req)
-	if err != nil {
-		return nil, 0, err
-	}
-	defer closeHTTPBody(resp.Body)
-
-	if resp.StatusCode != http.StatusOK {
-		return nil, 0, fmt.Errorf("dns: server returned HTTP %d error: %q", resp.StatusCode, resp.Status)
-	}
-
-	if ct := resp.Header.Get("Content-Type"); ct != dohMimeType {
-		return nil, 0, fmt.Errorf("dns: unexpected Content-Type %q; expected %q", ct, dohMimeType)
-	}
-
-	p, err = ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, 0, err
-	}
-
-	rtt = time.Since(t)
-
-	r = new(Msg)
-	if err := r.Unpack(p); err != nil {
-		return r, 0, err
-	}
-
-	// TODO: TSIG? Is it even supported over DoH?
-
-	return r, rtt, nil
-}
-
-func closeHTTPBody(r io.ReadCloser) error {
-	io.Copy(ioutil.Discard, io.LimitReader(r, 8<<20))
-	return r.Close()
-}
-
 // ReadMsg reads a message from the connection co.
 // If the received message contains a TSIG record the transaction signature
 // is verified. This method always tries to return the message, however if an
@@ -559,10 +482,6 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
 // context, if present. If there is both a context deadline and a configured
 // timeout on the client, the earliest of the two takes effect.
 func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
-	if !c.SingleInflight && c.Net == "https" {
-		return c.exchangeDOH(ctx, m, a)
-	}
-
 	var timeout time.Duration
 	if deadline, ok := ctx.Deadline(); !ok {
 		timeout = 0
@@ -571,7 +490,7 @@ func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg,
 	}
 	// not passing the context to the underlying calls, as the API does not support
 	// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
-	// TODO(tmthrgd): this is a race condition
+	// TODO(tmthrgd,miekg): this is a race condition.
 	c.Dialer = &net.Dialer{Timeout: timeout}
 	return c.Exchange(m, a)
 }
diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go
index 4b4ec33c8..06984e7ca 100644
--- a/vendor/github.com/miekg/dns/server.go
+++ b/vendor/github.com/miekg/dns/server.go
@@ -82,6 +82,7 @@ type ConnectionStater interface {
 
 type response struct {
 	msg            []byte
+	closed         bool // connection has been closed
 	hijacked       bool // connection has been hijacked by handler
 	tsigTimersOnly bool
 	tsigStatus     error
@@ -728,6 +729,10 @@ func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *S
 
 // WriteMsg implements the ResponseWriter.WriteMsg method.
 func (w *response) WriteMsg(m *Msg) (err error) {
+	if w.closed {
+		return &Error{err: "WriteMsg called after Close"}
+	}
+
 	var data []byte
 	if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check)
 		if t := m.IsTsig(); t != nil {
@@ -749,6 +754,10 @@ func (w *response) WriteMsg(m *Msg) (err error) {
 
 // Write implements the ResponseWriter.Write method.
 func (w *response) Write(m []byte) (int, error) {
+	if w.closed {
+		return 0, &Error{err: "Write called after Close"}
+	}
+
 	switch {
 	case w.udp != nil:
 		n, err := WriteToSessionUDP(w.udp, m, w.udpSession)
@@ -768,7 +777,7 @@ func (w *response) Write(m []byte) (int, error) {
 		n, err := io.Copy(w.tcp, bytes.NewReader(m))
 		return int(n), err
 	default:
-		panic("dns: Write called after Close")
+		panic("dns: internal error: udp and tcp both nil")
 	}
 }
 
@@ -780,7 +789,7 @@ func (w *response) LocalAddr() net.Addr {
 	case w.tcp != nil:
 		return w.tcp.LocalAddr()
 	default:
-		panic("dns: LocalAddr called after Close")
+		panic("dns: internal error: udp and tcp both nil")
 	}
 }
 
@@ -792,7 +801,7 @@ func (w *response) RemoteAddr() net.Addr {
 	case w.tcp != nil:
 		return w.tcp.RemoteAddr()
 	default:
-		panic("dns: RemoteAddr called after Close")
+		panic("dns: internal error: udpSession and tcp both nil")
 	}
 }
 
@@ -807,13 +816,20 @@ func (w *response) Hijack() { w.hijacked = true }
 
 // Close implements the ResponseWriter.Close method
 func (w *response) Close() error {
-	// Can't close the udp conn, as that is actually the listener.
-	if w.tcp != nil {
-		e := w.tcp.Close()
-		w.tcp = nil
-		return e
+	if w.closed {
+		return &Error{err: "connection already closed"}
+	}
+	w.closed = true
+
+	switch {
+	case w.udp != nil:
+		// Can't close the udp conn, as that is actually the listener.
+		return nil
+	case w.tcp != nil:
+		return w.tcp.Close()
+	default:
+		panic("dns: internal error: udp and tcp both nil")
 	}
-	return nil
 }
 
 // ConnectionState() implements the ConnectionStater.ConnectionState() interface.
diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go
index 0b0e9b6d8..e7c82e999 100644
--- a/vendor/github.com/miekg/dns/version.go
+++ b/vendor/github.com/miekg/dns/version.go
@@ -3,7 +3,7 @@ package dns
 import "fmt"
 
 // Version is current version of this library.
-var Version = V{1, 0, 14}
+var Version = V{1, 0, 15}
 
 // V holds the version of this library.
 type V struct {
diff --git a/vendor/github.com/mitchellh/go-homedir/README.md b/vendor/github.com/mitchellh/go-homedir/README.md
new file mode 100644
index 000000000..d70706d5b
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-homedir/README.md
@@ -0,0 +1,14 @@
+# go-homedir
+
+This is a Go library for detecting the user's home directory without
+the use of cgo, so the library can be used in cross-compilation environments.
+
+Usage is incredibly simple, just call `homedir.Dir()` to get the home directory
+for a user, and `homedir.Expand()` to expand the `~` in a path to the home
+directory.
+
+**Why not just use `os/user`?** The built-in `os/user` package requires
+cgo on Darwin systems. This means that any Go code that uses that package
+cannot cross compile. But 99% of the time the use for `os/user` is just to
+retrieve the home directory, which we can do for the current user without
+cgo. This library does that, enabling cross-compilation.
diff --git a/vendor/github.com/mitchellh/go-homedir/go.mod b/vendor/github.com/mitchellh/go-homedir/go.mod
new file mode 100644
index 000000000..7efa09a04
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-homedir/go.mod
@@ -0,0 +1 @@
+module github.com/mitchellh/go-homedir
diff --git a/vendor/github.com/modern-go/concurrent/LICENSE b/vendor/github.com/modern-go/concurrent/LICENSE
deleted file mode 100644
index 261eeb9e9..000000000
--- a/vendor/github.com/modern-go/concurrent/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/modern-go/concurrent/executor.go b/vendor/github.com/modern-go/concurrent/executor.go
deleted file mode 100644
index 623dba1ac..000000000
--- a/vendor/github.com/modern-go/concurrent/executor.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package concurrent
-
-import "context"
-
-// Executor replace go keyword to start a new goroutine
-// the goroutine should cancel itself if the context passed in has been cancelled
-// the goroutine started by the executor, is owned by the executor
-// we can cancel all executors owned by the executor just by stop the executor itself
-// however Executor interface does not Stop method, the one starting and owning executor
-// should use the concrete type of executor, instead of this interface.
-type Executor interface {
-	// Go starts a new goroutine controlled by the context
-	Go(handler func(ctx context.Context))
-}
diff --git a/vendor/github.com/modern-go/concurrent/go_above_19.go b/vendor/github.com/modern-go/concurrent/go_above_19.go
deleted file mode 100644
index aeabf8c4f..000000000
--- a/vendor/github.com/modern-go/concurrent/go_above_19.go
+++ /dev/null
@@ -1,15 +0,0 @@
-//+build go1.9
-
-package concurrent
-
-import "sync"
-
-// Map is a wrapper for sync.Map introduced in go1.9
-type Map struct {
-	sync.Map
-}
-
-// NewMap creates a thread safe Map
-func NewMap() *Map {
-	return &Map{}
-}
diff --git a/vendor/github.com/modern-go/concurrent/go_below_19.go b/vendor/github.com/modern-go/concurrent/go_below_19.go
deleted file mode 100644
index b9c8df7f4..000000000
--- a/vendor/github.com/modern-go/concurrent/go_below_19.go
+++ /dev/null
@@ -1,33 +0,0 @@
-//+build !go1.9
-
-package concurrent
-
-import "sync"
-
-// Map implements a thread safe map for go version below 1.9 using mutex
-type Map struct {
-	lock sync.RWMutex
-	data map[interface{}]interface{}
-}
-
-// NewMap creates a thread safe map
-func NewMap() *Map {
-	return &Map{
-		data: make(map[interface{}]interface{}, 32),
-	}
-}
-
-// Load is same as sync.Map Load
-func (m *Map) Load(key interface{}) (elem interface{}, found bool) {
-	m.lock.RLock()
-	elem, found = m.data[key]
-	m.lock.RUnlock()
-	return
-}
-
-// Load is same as sync.Map Store
-func (m *Map) Store(key interface{}, elem interface{}) {
-	m.lock.Lock()
-	m.data[key] = elem
-	m.lock.Unlock()
-}
diff --git a/vendor/github.com/modern-go/concurrent/log.go b/vendor/github.com/modern-go/concurrent/log.go
deleted file mode 100644
index 9756fcc75..000000000
--- a/vendor/github.com/modern-go/concurrent/log.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package concurrent
-
-import (
-	"os"
-	"log"
-	"io/ioutil"
-)
-
-// ErrorLogger is used to print out error, can be set to writer other than stderr
-var ErrorLogger = log.New(os.Stderr, "", 0)
-
-// InfoLogger is used to print informational message, default to off
-var InfoLogger = log.New(ioutil.Discard, "", 0)
\ No newline at end of file
diff --git a/vendor/github.com/modern-go/concurrent/unbounded_executor.go b/vendor/github.com/modern-go/concurrent/unbounded_executor.go
deleted file mode 100644
index 05a77dceb..000000000
--- a/vendor/github.com/modern-go/concurrent/unbounded_executor.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package concurrent
-
-import (
-	"context"
-	"fmt"
-	"runtime"
-	"runtime/debug"
-	"sync"
-	"time"
-	"reflect"
-)
-
-// HandlePanic logs goroutine panic by default
-var HandlePanic = func(recovered interface{}, funcName string) {
-	ErrorLogger.Println(fmt.Sprintf("%s panic: %v", funcName, recovered))
-	ErrorLogger.Println(string(debug.Stack()))
-}
-
-// UnboundedExecutor is a executor without limits on counts of alive goroutines
-// it tracks the goroutine started by it, and can cancel them when shutdown
-type UnboundedExecutor struct {
-	ctx                   context.Context
-	cancel                context.CancelFunc
-	activeGoroutinesMutex *sync.Mutex
-	activeGoroutines      map[string]int
-	HandlePanic           func(recovered interface{}, funcName string)
-}
-
-// GlobalUnboundedExecutor has the life cycle of the program itself
-// any goroutine want to be shutdown before main exit can be started from this executor
-// GlobalUnboundedExecutor expects the main function to call stop
-// it does not magically knows the main function exits
-var GlobalUnboundedExecutor = NewUnboundedExecutor()
-
-// NewUnboundedExecutor creates a new UnboundedExecutor,
-// UnboundedExecutor can not be created by &UnboundedExecutor{}
-// HandlePanic can be set with a callback to override global HandlePanic
-func NewUnboundedExecutor() *UnboundedExecutor {
-	ctx, cancel := context.WithCancel(context.TODO())
-	return &UnboundedExecutor{
-		ctx:                   ctx,
-		cancel:                cancel,
-		activeGoroutinesMutex: &sync.Mutex{},
-		activeGoroutines:      map[string]int{},
-	}
-}
-
-// Go starts a new goroutine and tracks its lifecycle.
-// Panic will be recovered and logged automatically, except for StopSignal
-func (executor *UnboundedExecutor) Go(handler func(ctx context.Context)) {
-	pc := reflect.ValueOf(handler).Pointer()
-	f := runtime.FuncForPC(pc)
-	funcName := f.Name()
-	file, line := f.FileLine(pc)
-	executor.activeGoroutinesMutex.Lock()
-	defer executor.activeGoroutinesMutex.Unlock()
-	startFrom := fmt.Sprintf("%s:%d", file, line)
-	executor.activeGoroutines[startFrom] += 1
-	go func() {
-		defer func() {
-			recovered := recover()
-			// if you want to quit a goroutine without trigger HandlePanic
-			// use runtime.Goexit() to quit
-			if recovered != nil {
-				if executor.HandlePanic == nil {
-					HandlePanic(recovered, funcName)
-				} else {
-					executor.HandlePanic(recovered, funcName)
-				}
-			}
-			executor.activeGoroutinesMutex.Lock()
-			executor.activeGoroutines[startFrom] -= 1
-			executor.activeGoroutinesMutex.Unlock()
-		}()
-		handler(executor.ctx)
-	}()
-}
-
-// Stop cancel all goroutines started by this executor without wait
-func (executor *UnboundedExecutor) Stop() {
-	executor.cancel()
-}
-
-// StopAndWaitForever cancel all goroutines started by this executor and
-// wait until all goroutines exited
-func (executor *UnboundedExecutor) StopAndWaitForever() {
-	executor.StopAndWait(context.Background())
-}
-
-// StopAndWait cancel all goroutines started by this executor and wait.
-// Wait can be cancelled by the context passed in.
-func (executor *UnboundedExecutor) StopAndWait(ctx context.Context) {
-	executor.cancel()
-	for {
-		oneHundredMilliseconds := time.NewTimer(time.Millisecond * 100)
-		select {
-		case <-oneHundredMilliseconds.C:
-			if executor.checkNoActiveGoroutines() {
-				return
-			}
-		case <-ctx.Done():
-			return
-		}
-	}
-}
-
-func (executor *UnboundedExecutor) checkNoActiveGoroutines() bool {
-	executor.activeGoroutinesMutex.Lock()
-	defer executor.activeGoroutinesMutex.Unlock()
-	for startFrom, count := range executor.activeGoroutines {
-		if count > 0 {
-			InfoLogger.Println("UnboundedExecutor is still waiting goroutines to quit",
-				"startFrom", startFrom,
-				"count", count)
-			return false
-		}
-	}
-	return true
-}
diff --git a/vendor/github.com/modern-go/reflect2/LICENSE b/vendor/github.com/modern-go/reflect2/LICENSE
deleted file mode 100644
index 261eeb9e9..000000000
--- a/vendor/github.com/modern-go/reflect2/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/modern-go/reflect2/go_above_17.go b/vendor/github.com/modern-go/reflect2/go_above_17.go
deleted file mode 100644
index 5c1cea868..000000000
--- a/vendor/github.com/modern-go/reflect2/go_above_17.go
+++ /dev/null
@@ -1,8 +0,0 @@
-//+build go1.7
-
-package reflect2
-
-import "unsafe"
-
-//go:linkname resolveTypeOff reflect.resolveTypeOff
-func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
diff --git a/vendor/github.com/modern-go/reflect2/go_above_19.go b/vendor/github.com/modern-go/reflect2/go_above_19.go
deleted file mode 100644
index c7e3b7801..000000000
--- a/vendor/github.com/modern-go/reflect2/go_above_19.go
+++ /dev/null
@@ -1,14 +0,0 @@
-//+build go1.9
-
-package reflect2
-
-import (
-	"unsafe"
-)
-
-//go:linkname makemap reflect.makemap
-func makemap(rtype unsafe.Pointer, cap int) (m unsafe.Pointer)
-
-func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer {
-	return makemap(rtype, cap)
-}
diff --git a/vendor/github.com/modern-go/reflect2/go_below_17.go b/vendor/github.com/modern-go/reflect2/go_below_17.go
deleted file mode 100644
index 65a93c889..000000000
--- a/vendor/github.com/modern-go/reflect2/go_below_17.go
+++ /dev/null
@@ -1,9 +0,0 @@
-//+build !go1.7
-
-package reflect2
-
-import "unsafe"
-
-func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
-	return nil
-}
diff --git a/vendor/github.com/modern-go/reflect2/go_below_19.go b/vendor/github.com/modern-go/reflect2/go_below_19.go
deleted file mode 100644
index b050ef70c..000000000
--- a/vendor/github.com/modern-go/reflect2/go_below_19.go
+++ /dev/null
@@ -1,14 +0,0 @@
-//+build !go1.9
-
-package reflect2
-
-import (
-	"unsafe"
-)
-
-//go:linkname makemap reflect.makemap
-func makemap(rtype unsafe.Pointer) (m unsafe.Pointer)
-
-func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer {
-	return makemap(rtype)
-}
diff --git a/vendor/github.com/modern-go/reflect2/reflect2.go b/vendor/github.com/modern-go/reflect2/reflect2.go
deleted file mode 100644
index 63b49c799..000000000
--- a/vendor/github.com/modern-go/reflect2/reflect2.go
+++ /dev/null
@@ -1,298 +0,0 @@
-package reflect2
-
-import (
-	"github.com/modern-go/concurrent"
-	"reflect"
-	"unsafe"
-)
-
-type Type interface {
-	Kind() reflect.Kind
-	// New return pointer to data of this type
-	New() interface{}
-	// UnsafeNew return the allocated space pointed by unsafe.Pointer
-	UnsafeNew() unsafe.Pointer
-	// PackEFace cast a unsafe pointer to object represented pointer
-	PackEFace(ptr unsafe.Pointer) interface{}
-	// Indirect dereference object represented pointer to this type
-	Indirect(obj interface{}) interface{}
-	// UnsafeIndirect dereference pointer to this type
-	UnsafeIndirect(ptr unsafe.Pointer) interface{}
-	// Type1 returns reflect.Type
-	Type1() reflect.Type
-	Implements(thatType Type) bool
-	String() string
-	RType() uintptr
-	// interface{} of this type has pointer like behavior
-	LikePtr() bool
-	IsNullable() bool
-	IsNil(obj interface{}) bool
-	UnsafeIsNil(ptr unsafe.Pointer) bool
-	Set(obj interface{}, val interface{})
-	UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer)
-	AssignableTo(anotherType Type) bool
-}
-
-type ListType interface {
-	Type
-	Elem() Type
-	SetIndex(obj interface{}, index int, elem interface{})
-	UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer)
-	GetIndex(obj interface{}, index int) interface{}
-	UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer
-}
-
-type ArrayType interface {
-	ListType
-	Len() int
-}
-
-type SliceType interface {
-	ListType
-	MakeSlice(length int, cap int) interface{}
-	UnsafeMakeSlice(length int, cap int) unsafe.Pointer
-	Grow(obj interface{}, newLength int)
-	UnsafeGrow(ptr unsafe.Pointer, newLength int)
-	Append(obj interface{}, elem interface{})
-	UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer)
-	LengthOf(obj interface{}) int
-	UnsafeLengthOf(ptr unsafe.Pointer) int
-	SetNil(obj interface{})
-	UnsafeSetNil(ptr unsafe.Pointer)
-	Cap(obj interface{}) int
-	UnsafeCap(ptr unsafe.Pointer) int
-}
-
-type StructType interface {
-	Type
-	NumField() int
-	Field(i int) StructField
-	FieldByName(name string) StructField
-	FieldByIndex(index []int) StructField
-	FieldByNameFunc(match func(string) bool) StructField
-}
-
-type StructField interface {
-	Offset() uintptr
-	Name() string
-	PkgPath() string
-	Type() Type
-	Tag() reflect.StructTag
-	Index() []int
-	Anonymous() bool
-	Set(obj interface{}, value interface{})
-	UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer)
-	Get(obj interface{}) interface{}
-	UnsafeGet(obj unsafe.Pointer) unsafe.Pointer
-}
-
-type MapType interface {
-	Type
-	Key() Type
-	Elem() Type
-	MakeMap(cap int) interface{}
-	UnsafeMakeMap(cap int) unsafe.Pointer
-	SetIndex(obj interface{}, key interface{}, elem interface{})
-	UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer)
-	TryGetIndex(obj interface{}, key interface{}) (interface{}, bool)
-	GetIndex(obj interface{}, key interface{}) interface{}
-	UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
-	Iterate(obj interface{}) MapIterator
-	UnsafeIterate(obj unsafe.Pointer) MapIterator
-}
-
-type MapIterator interface {
-	HasNext() bool
-	Next() (key interface{}, elem interface{})
-	UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer)
-}
-
-type PtrType interface {
-	Type
-	Elem() Type
-}
-
-type InterfaceType interface {
-	NumMethod() int
-}
-
-type Config struct {
-	UseSafeImplementation bool
-}
-
-type API interface {
-	TypeOf(obj interface{}) Type
-	Type2(type1 reflect.Type) Type
-}
-
-var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze()
-var ConfigSafe = Config{UseSafeImplementation: true}.Froze()
-
-type frozenConfig struct {
-	useSafeImplementation bool
-	cache                 *concurrent.Map
-}
-
-func (cfg Config) Froze() *frozenConfig {
-	return &frozenConfig{
-		useSafeImplementation: cfg.UseSafeImplementation,
-		cache: concurrent.NewMap(),
-	}
-}
-
-func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
-	cacheKey := uintptr(unpackEFace(obj).rtype)
-	typeObj, found := cfg.cache.Load(cacheKey)
-	if found {
-		return typeObj.(Type)
-	}
-	return cfg.Type2(reflect.TypeOf(obj))
-}
-
-func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
-	if type1 == nil {
-		return nil
-	}
-	cacheKey := uintptr(unpackEFace(type1).data)
-	typeObj, found := cfg.cache.Load(cacheKey)
-	if found {
-		return typeObj.(Type)
-	}
-	type2 := cfg.wrapType(type1)
-	cfg.cache.Store(cacheKey, type2)
-	return type2
-}
-
-func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type {
-	safeType := safeType{Type: type1, cfg: cfg}
-	switch type1.Kind() {
-	case reflect.Struct:
-		if cfg.useSafeImplementation {
-			return &safeStructType{safeType}
-		}
-		return newUnsafeStructType(cfg, type1)
-	case reflect.Array:
-		if cfg.useSafeImplementation {
-			return &safeSliceType{safeType}
-		}
-		return newUnsafeArrayType(cfg, type1)
-	case reflect.Slice:
-		if cfg.useSafeImplementation {
-			return &safeSliceType{safeType}
-		}
-		return newUnsafeSliceType(cfg, type1)
-	case reflect.Map:
-		if cfg.useSafeImplementation {
-			return &safeMapType{safeType}
-		}
-		return newUnsafeMapType(cfg, type1)
-	case reflect.Ptr, reflect.Chan, reflect.Func:
-		if cfg.useSafeImplementation {
-			return &safeMapType{safeType}
-		}
-		return newUnsafePtrType(cfg, type1)
-	case reflect.Interface:
-		if cfg.useSafeImplementation {
-			return &safeMapType{safeType}
-		}
-		if type1.NumMethod() == 0 {
-			return newUnsafeEFaceType(cfg, type1)
-		}
-		return newUnsafeIFaceType(cfg, type1)
-	default:
-		if cfg.useSafeImplementation {
-			return &safeType
-		}
-		return newUnsafeType(cfg, type1)
-	}
-}
-
-func TypeOf(obj interface{}) Type {
-	return ConfigUnsafe.TypeOf(obj)
-}
-
-func TypeOfPtr(obj interface{}) PtrType {
-	return TypeOf(obj).(PtrType)
-}
-
-func Type2(type1 reflect.Type) Type {
-	if type1 == nil {
-		return nil
-	}
-	return ConfigUnsafe.Type2(type1)
-}
-
-func PtrTo(typ Type) Type {
-	return Type2(reflect.PtrTo(typ.Type1()))
-}
-
-func PtrOf(obj interface{}) unsafe.Pointer {
-	return unpackEFace(obj).data
-}
-
-func RTypeOf(obj interface{}) uintptr {
-	return uintptr(unpackEFace(obj).rtype)
-}
-
-func IsNil(obj interface{}) bool {
-	if obj == nil {
-		return true
-	}
-	return unpackEFace(obj).data == nil
-}
-
-func IsNullable(kind reflect.Kind) bool {
-	switch kind {
-	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface:
-		return true
-	}
-	return false
-}
-
-func likePtrKind(kind reflect.Kind) bool {
-	switch kind {
-	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func:
-		return true
-	}
-	return false
-}
-
-func likePtrType(typ reflect.Type) bool {
-	if likePtrKind(typ.Kind()) {
-		return true
-	}
-	if typ.Kind() == reflect.Struct {
-		if typ.NumField() != 1 {
-			return false
-		}
-		return likePtrType(typ.Field(0).Type)
-	}
-	if typ.Kind() == reflect.Array {
-		if typ.Len() != 1 {
-			return false
-		}
-		return likePtrType(typ.Elem())
-	}
-	return false
-}
-
-// NoEscape hides a pointer from escape analysis.  noescape is
-// the identity function but escape analysis doesn't think the
-// output depends on the input.  noescape is inlined and currently
-// compiles down to zero instructions.
-// USE CAREFULLY!
-//go:nosplit
-func NoEscape(p unsafe.Pointer) unsafe.Pointer {
-	x := uintptr(p)
-	return unsafe.Pointer(x ^ 0)
-}
-
-func UnsafeCastString(str string) []byte {
-	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
-	sliceHeader := &reflect.SliceHeader{
-		Data: stringHeader.Data,
-		Cap: stringHeader.Len,
-		Len: stringHeader.Len,
-	}
-	return *(*[]byte)(unsafe.Pointer(sliceHeader))
-}
diff --git a/vendor/github.com/modern-go/reflect2/reflect2_amd64.s b/vendor/github.com/modern-go/reflect2/reflect2_amd64.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/reflect2_kind.go b/vendor/github.com/modern-go/reflect2/reflect2_kind.go
deleted file mode 100644
index 62f299e40..000000000
--- a/vendor/github.com/modern-go/reflect2/reflect2_kind.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-// DefaultTypeOfKind return the non aliased default type for the kind
-func DefaultTypeOfKind(kind reflect.Kind) Type {
-	return kindTypes[kind]
-}
-
-var kindTypes = map[reflect.Kind]Type{
-	reflect.Bool:          TypeOf(true),
-	reflect.Uint8:         TypeOf(uint8(0)),
-	reflect.Int8:          TypeOf(int8(0)),
-	reflect.Uint16:        TypeOf(uint16(0)),
-	reflect.Int16:         TypeOf(int16(0)),
-	reflect.Uint32:        TypeOf(uint32(0)),
-	reflect.Int32:         TypeOf(int32(0)),
-	reflect.Uint64:        TypeOf(uint64(0)),
-	reflect.Int64:         TypeOf(int64(0)),
-	reflect.Uint:          TypeOf(uint(0)),
-	reflect.Int:           TypeOf(int(0)),
-	reflect.Float32:       TypeOf(float32(0)),
-	reflect.Float64:       TypeOf(float64(0)),
-	reflect.Uintptr:       TypeOf(uintptr(0)),
-	reflect.String:        TypeOf(""),
-	reflect.UnsafePointer: TypeOf(unsafe.Pointer(nil)),
-}
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_386.s b/vendor/github.com/modern-go/reflect2/relfect2_386.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s b/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm.s b/vendor/github.com/modern-go/reflect2/relfect2_arm.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm64.s b/vendor/github.com/modern-go/reflect2/relfect2_arm64.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s b/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s b/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s b/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/relfect2_s390x.s b/vendor/github.com/modern-go/reflect2/relfect2_s390x.s
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendor/github.com/modern-go/reflect2/safe_field.go b/vendor/github.com/modern-go/reflect2/safe_field.go
deleted file mode 100644
index d4ba1f4f8..000000000
--- a/vendor/github.com/modern-go/reflect2/safe_field.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type safeField struct {
-	reflect.StructField
-}
-
-func (field *safeField) Offset() uintptr {
-	return field.StructField.Offset
-}
-
-func (field *safeField) Name() string {
-	return field.StructField.Name
-}
-
-func (field *safeField) PkgPath() string {
-	return field.StructField.PkgPath
-}
-
-func (field *safeField) Type() Type {
-	panic("not implemented")
-}
-
-func (field *safeField) Tag() reflect.StructTag {
-	return field.StructField.Tag
-}
-
-func (field *safeField) Index() []int {
-	return field.StructField.Index
-}
-
-func (field *safeField) Anonymous() bool {
-	return field.StructField.Anonymous
-}
-
-func (field *safeField) Set(obj interface{}, value interface{}) {
-	val := reflect.ValueOf(obj).Elem()
-	val.FieldByIndex(field.Index()).Set(reflect.ValueOf(value).Elem())
-}
-
-func (field *safeField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) {
-	panic("unsafe operation is not supported")
-}
-
-func (field *safeField) Get(obj interface{}) interface{} {
-	val := reflect.ValueOf(obj).Elem().FieldByIndex(field.Index())
-	ptr := reflect.New(val.Type())
-	ptr.Elem().Set(val)
-	return ptr.Interface()
-}
-
-func (field *safeField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer {
-	panic("does not support unsafe operation")
-}
diff --git a/vendor/github.com/modern-go/reflect2/safe_map.go b/vendor/github.com/modern-go/reflect2/safe_map.go
deleted file mode 100644
index 88362205a..000000000
--- a/vendor/github.com/modern-go/reflect2/safe_map.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type safeMapType struct {
-	safeType
-}
-
-func (type2 *safeMapType) Key() Type {
-	return type2.safeType.cfg.Type2(type2.Type.Key())
-}
-
-func (type2 *safeMapType) MakeMap(cap int) interface{} {
-	ptr := reflect.New(type2.Type)
-	ptr.Elem().Set(reflect.MakeMap(type2.Type))
-	return ptr.Interface()
-}
-
-func (type2 *safeMapType) UnsafeMakeMap(cap int) unsafe.Pointer {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) {
-	keyVal := reflect.ValueOf(key)
-	elemVal := reflect.ValueOf(elem)
-	val := reflect.ValueOf(obj)
-	val.Elem().SetMapIndex(keyVal.Elem(), elemVal.Elem())
-}
-
-func (type2 *safeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) {
-	keyVal := reflect.ValueOf(key)
-	if key == nil {
-		keyVal = reflect.New(type2.Type.Key()).Elem()
-	}
-	val := reflect.ValueOf(obj).MapIndex(keyVal)
-	if !val.IsValid() {
-		return nil, false
-	}
-	return val.Interface(), true
-}
-
-func (type2 *safeMapType) GetIndex(obj interface{}, key interface{}) interface{} {
-	val := reflect.ValueOf(obj).Elem()
-	keyVal := reflect.ValueOf(key).Elem()
-	elemVal := val.MapIndex(keyVal)
-	if !elemVal.IsValid() {
-		ptr := reflect.New(reflect.PtrTo(val.Type().Elem()))
-		return ptr.Elem().Interface()
-	}
-	ptr := reflect.New(elemVal.Type())
-	ptr.Elem().Set(elemVal)
-	return ptr.Interface()
-}
-
-func (type2 *safeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeMapType) Iterate(obj interface{}) MapIterator {
-	m := reflect.ValueOf(obj).Elem()
-	return &safeMapIterator{
-		m:    m,
-		keys: m.MapKeys(),
-	}
-}
-
-func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
-	panic("does not support unsafe operation")
-}
-
-type safeMapIterator struct {
-	i    int
-	m    reflect.Value
-	keys []reflect.Value
-}
-
-func (iter *safeMapIterator) HasNext() bool {
-	return iter.i != len(iter.keys)
-}
-
-func (iter *safeMapIterator) Next() (interface{}, interface{}) {
-	key := iter.keys[iter.i]
-	elem := iter.m.MapIndex(key)
-	iter.i += 1
-	keyPtr := reflect.New(key.Type())
-	keyPtr.Elem().Set(key)
-	elemPtr := reflect.New(elem.Type())
-	elemPtr.Elem().Set(elem)
-	return keyPtr.Interface(), elemPtr.Interface()
-}
-
-func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) {
-	panic("does not support unsafe operation")
-}
diff --git a/vendor/github.com/modern-go/reflect2/safe_slice.go b/vendor/github.com/modern-go/reflect2/safe_slice.go
deleted file mode 100644
index bcce6fd20..000000000
--- a/vendor/github.com/modern-go/reflect2/safe_slice.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type safeSliceType struct {
-	safeType
-}
-
-func (type2 *safeSliceType) SetIndex(obj interface{}, index int, value interface{}) {
-	val := reflect.ValueOf(obj).Elem()
-	elem := reflect.ValueOf(value).Elem()
-	val.Index(index).Set(elem)
-}
-
-func (type2 *safeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, value unsafe.Pointer) {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeSliceType) GetIndex(obj interface{}, index int) interface{} {
-	val := reflect.ValueOf(obj).Elem()
-	elem := val.Index(index)
-	ptr := reflect.New(elem.Type())
-	ptr.Elem().Set(elem)
-	return ptr.Interface()
-}
-
-func (type2 *safeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeSliceType) MakeSlice(length int, cap int) interface{} {
-	val := reflect.MakeSlice(type2.Type, length, cap)
-	ptr := reflect.New(val.Type())
-	ptr.Elem().Set(val)
-	return ptr.Interface()
-}
-
-func (type2 *safeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeSliceType) Grow(obj interface{}, newLength int) {
-	oldCap := type2.Cap(obj)
-	oldSlice := reflect.ValueOf(obj).Elem()
-	delta := newLength - oldCap
-	deltaVals := make([]reflect.Value, delta)
-	newSlice := reflect.Append(oldSlice, deltaVals...)
-	oldSlice.Set(newSlice)
-}
-
-func (type2 *safeSliceType) UnsafeGrow(ptr unsafe.Pointer, newLength int) {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeSliceType) Append(obj interface{}, elem interface{}) {
-	val := reflect.ValueOf(obj).Elem()
-	elemVal := reflect.ValueOf(elem).Elem()
-	newVal := reflect.Append(val, elemVal)
-	val.Set(newVal)
-}
-
-func (type2 *safeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeSliceType) SetNil(obj interface{}) {
-	val := reflect.ValueOf(obj).Elem()
-	val.Set(reflect.Zero(val.Type()))
-}
-
-func (type2 *safeSliceType) UnsafeSetNil(ptr unsafe.Pointer) {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeSliceType) LengthOf(obj interface{}) int {
-	return reflect.ValueOf(obj).Elem().Len()
-}
-
-func (type2 *safeSliceType) UnsafeLengthOf(ptr unsafe.Pointer) int {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeSliceType) Cap(obj interface{}) int {
-	return reflect.ValueOf(obj).Elem().Cap()
-}
-
-func (type2 *safeSliceType) UnsafeCap(ptr unsafe.Pointer) int {
-	panic("does not support unsafe operation")
-}
diff --git a/vendor/github.com/modern-go/reflect2/safe_struct.go b/vendor/github.com/modern-go/reflect2/safe_struct.go
deleted file mode 100644
index e5fb9b313..000000000
--- a/vendor/github.com/modern-go/reflect2/safe_struct.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package reflect2
-
-type safeStructType struct {
-	safeType
-}
-
-func (type2 *safeStructType) FieldByName(name string) StructField {
-	field, found := type2.Type.FieldByName(name)
-	if !found {
-		panic("field " + name + " not found")
-	}
-	return &safeField{StructField: field}
-}
-
-func (type2 *safeStructType) Field(i int) StructField {
-	return &safeField{StructField: type2.Type.Field(i)}
-}
-
-func (type2 *safeStructType) FieldByIndex(index []int) StructField {
-	return &safeField{StructField: type2.Type.FieldByIndex(index)}
-}
-
-func (type2 *safeStructType) FieldByNameFunc(match func(string) bool) StructField {
-	field, found := type2.Type.FieldByNameFunc(match)
-	if !found {
-		panic("field match condition not found in " + type2.Type.String())
-	}
-	return &safeField{StructField: field}
-}
diff --git a/vendor/github.com/modern-go/reflect2/safe_type.go b/vendor/github.com/modern-go/reflect2/safe_type.go
deleted file mode 100644
index ee4e7bb6e..000000000
--- a/vendor/github.com/modern-go/reflect2/safe_type.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type safeType struct {
-	reflect.Type
-	cfg *frozenConfig
-}
-
-func (type2 *safeType) New() interface{} {
-	return reflect.New(type2.Type).Interface()
-}
-
-func (type2 *safeType) UnsafeNew() unsafe.Pointer {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeType) Elem() Type {
-	return type2.cfg.Type2(type2.Type.Elem())
-}
-
-func (type2 *safeType) Type1() reflect.Type {
-	return type2.Type
-}
-
-func (type2 *safeType) PackEFace(ptr unsafe.Pointer) interface{} {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeType) Implements(thatType Type) bool {
-	return type2.Type.Implements(thatType.Type1())
-}
-
-func (type2 *safeType) RType() uintptr {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeType) Indirect(obj interface{}) interface{} {
-	return reflect.Indirect(reflect.ValueOf(obj)).Interface()
-}
-
-func (type2 *safeType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeType) LikePtr() bool {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeType) IsNullable() bool {
-	return IsNullable(type2.Kind())
-}
-
-func (type2 *safeType) IsNil(obj interface{}) bool {
-	if obj == nil {
-		return true
-	}
-	return reflect.ValueOf(obj).Elem().IsNil()
-}
-
-func (type2 *safeType) UnsafeIsNil(ptr unsafe.Pointer) bool {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeType) Set(obj interface{}, val interface{}) {
-	reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(val).Elem())
-}
-
-func (type2 *safeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
-	panic("does not support unsafe operation")
-}
-
-func (type2 *safeType) AssignableTo(anotherType Type) bool {
-	return type2.Type1().AssignableTo(anotherType.Type1())
-}
diff --git a/vendor/github.com/modern-go/reflect2/type_map.go b/vendor/github.com/modern-go/reflect2/type_map.go
deleted file mode 100644
index 6d489112f..000000000
--- a/vendor/github.com/modern-go/reflect2/type_map.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"runtime"
-	"strings"
-	"unsafe"
-)
-
-// typelinks1 for 1.5 ~ 1.6
-//go:linkname typelinks1 reflect.typelinks
-func typelinks1() [][]unsafe.Pointer
-
-// typelinks2 for 1.7 ~
-//go:linkname typelinks2 reflect.typelinks
-func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
-
-var types = map[string]reflect.Type{}
-var packages = map[string]map[string]reflect.Type{}
-
-func init() {
-	ver := runtime.Version()
-	if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") {
-		loadGo15Types()
-	} else if ver == "go1.6" || strings.HasPrefix(ver, "go1.6.") {
-		loadGo15Types()
-	} else {
-		loadGo17Types()
-	}
-}
-
-func loadGo15Types() {
-	var obj interface{} = reflect.TypeOf(0)
-	typePtrss := typelinks1()
-	for _, typePtrs := range typePtrss {
-		for _, typePtr := range typePtrs {
-			(*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr
-			typ := obj.(reflect.Type)
-			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
-				loadedType := typ.Elem()
-				pkgTypes := packages[loadedType.PkgPath()]
-				if pkgTypes == nil {
-					pkgTypes = map[string]reflect.Type{}
-					packages[loadedType.PkgPath()] = pkgTypes
-				}
-				types[loadedType.String()] = loadedType
-				pkgTypes[loadedType.Name()] = loadedType
-			}
-			if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr &&
-				typ.Elem().Elem().Kind() == reflect.Struct {
-				loadedType := typ.Elem().Elem()
-				pkgTypes := packages[loadedType.PkgPath()]
-				if pkgTypes == nil {
-					pkgTypes = map[string]reflect.Type{}
-					packages[loadedType.PkgPath()] = pkgTypes
-				}
-				types[loadedType.String()] = loadedType
-				pkgTypes[loadedType.Name()] = loadedType
-			}
-		}
-	}
-}
-
-func loadGo17Types() {
-	var obj interface{} = reflect.TypeOf(0)
-	sections, offset := typelinks2()
-	for i, offs := range offset {
-		rodata := sections[i]
-		for _, off := range offs {
-			(*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off)
-			typ := obj.(reflect.Type)
-			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
-				loadedType := typ.Elem()
-				pkgTypes := packages[loadedType.PkgPath()]
-				if pkgTypes == nil {
-					pkgTypes = map[string]reflect.Type{}
-					packages[loadedType.PkgPath()] = pkgTypes
-				}
-				types[loadedType.String()] = loadedType
-				pkgTypes[loadedType.Name()] = loadedType
-			}
-		}
-	}
-}
-
-type emptyInterface struct {
-	typ  unsafe.Pointer
-	word unsafe.Pointer
-}
-
-// TypeByName return the type by its name, just like Class.forName in java
-func TypeByName(typeName string) Type {
-	return Type2(types[typeName])
-}
-
-// TypeByPackageName return the type by its package and name
-func TypeByPackageName(pkgPath string, name string) Type {
-	pkgTypes := packages[pkgPath]
-	if pkgTypes == nil {
-		return nil
-	}
-	return Type2(pkgTypes[name])
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_array.go b/vendor/github.com/modern-go/reflect2/unsafe_array.go
deleted file mode 100644
index 76cbdba6e..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_array.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type UnsafeArrayType struct {
-	unsafeType
-	elemRType  unsafe.Pointer
-	pElemRType unsafe.Pointer
-	elemSize   uintptr
-	likePtr    bool
-}
-
-func newUnsafeArrayType(cfg *frozenConfig, type1 reflect.Type) *UnsafeArrayType {
-	return &UnsafeArrayType{
-		unsafeType: *newUnsafeType(cfg, type1),
-		elemRType:  unpackEFace(type1.Elem()).data,
-		pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data,
-		elemSize:   type1.Elem().Size(),
-		likePtr:    likePtrType(type1),
-	}
-}
-
-func (type2 *UnsafeArrayType) LikePtr() bool {
-	return type2.likePtr
-}
-
-func (type2 *UnsafeArrayType) Indirect(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIndirect(objEFace.data)
-}
-
-func (type2 *UnsafeArrayType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
-	if type2.likePtr {
-		return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
-	}
-	return packEFace(type2.rtype, ptr)
-}
-
-func (type2 *UnsafeArrayType) SetIndex(obj interface{}, index int, elem interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("ArrayType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
-	elemEFace := unpackEFace(elem)
-	assertType("ArrayType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
-	type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data)
-}
-
-func (type2 *UnsafeArrayType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) {
-	elemPtr := arrayAt(obj, index, type2.elemSize, "i < s.Len")
-	typedmemmove(type2.elemRType, elemPtr, elem)
-}
-
-func (type2 *UnsafeArrayType) GetIndex(obj interface{}, index int) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("ArrayType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
-	elemPtr := type2.UnsafeGetIndex(objEFace.data, index)
-	return packEFace(type2.pElemRType, elemPtr)
-}
-
-func (type2 *UnsafeArrayType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer {
-	return arrayAt(obj, index, type2.elemSize, "i < s.Len")
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_eface.go b/vendor/github.com/modern-go/reflect2/unsafe_eface.go
deleted file mode 100644
index 805010f3a..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_eface.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type eface struct {
-	rtype unsafe.Pointer
-	data  unsafe.Pointer
-}
-
-func unpackEFace(obj interface{}) *eface {
-	return (*eface)(unsafe.Pointer(&obj))
-}
-
-func packEFace(rtype unsafe.Pointer, data unsafe.Pointer) interface{} {
-	var i interface{}
-	e := (*eface)(unsafe.Pointer(&i))
-	e.rtype = rtype
-	e.data = data
-	return i
-}
-
-type UnsafeEFaceType struct {
-	unsafeType
-}
-
-func newUnsafeEFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeEFaceType {
-	return &UnsafeEFaceType{
-		unsafeType: *newUnsafeType(cfg, type1),
-	}
-}
-
-func (type2 *UnsafeEFaceType) IsNil(obj interface{}) bool {
-	if obj == nil {
-		return true
-	}
-	objEFace := unpackEFace(obj)
-	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIsNil(objEFace.data)
-}
-
-func (type2 *UnsafeEFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
-	if ptr == nil {
-		return true
-	}
-	return unpackEFace(*(*interface{})(ptr)).data == nil
-}
-
-func (type2 *UnsafeEFaceType) Indirect(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIndirect(objEFace.data)
-}
-
-func (type2 *UnsafeEFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
-	return *(*interface{})(ptr)
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_field.go b/vendor/github.com/modern-go/reflect2/unsafe_field.go
deleted file mode 100644
index 5eb53130a..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_field.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type UnsafeStructField struct {
-	reflect.StructField
-	structType *UnsafeStructType
-	rtype      unsafe.Pointer
-	ptrRType   unsafe.Pointer
-}
-
-func newUnsafeStructField(structType *UnsafeStructType, structField reflect.StructField) *UnsafeStructField {
-	return &UnsafeStructField{
-		StructField: structField,
-		rtype:       unpackEFace(structField.Type).data,
-		ptrRType:    unpackEFace(reflect.PtrTo(structField.Type)).data,
-		structType:  structType,
-	}
-}
-
-func (field *UnsafeStructField) Offset() uintptr {
-	return field.StructField.Offset
-}
-
-func (field *UnsafeStructField) Name() string {
-	return field.StructField.Name
-}
-
-func (field *UnsafeStructField) PkgPath() string {
-	return field.StructField.PkgPath
-}
-
-func (field *UnsafeStructField) Type() Type {
-	return field.structType.cfg.Type2(field.StructField.Type)
-}
-
-func (field *UnsafeStructField) Tag() reflect.StructTag {
-	return field.StructField.Tag
-}
-
-func (field *UnsafeStructField) Index() []int {
-	return field.StructField.Index
-}
-
-func (field *UnsafeStructField) Anonymous() bool {
-	return field.StructField.Anonymous
-}
-
-func (field *UnsafeStructField) Set(obj interface{}, value interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("StructField.SetIndex argument 1", field.structType.ptrRType, objEFace.rtype)
-	valueEFace := unpackEFace(value)
-	assertType("StructField.SetIndex argument 2", field.ptrRType, valueEFace.rtype)
-	field.UnsafeSet(objEFace.data, valueEFace.data)
-}
-
-func (field *UnsafeStructField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) {
-	fieldPtr := add(obj, field.StructField.Offset, "same as non-reflect &v.field")
-	typedmemmove(field.rtype, fieldPtr, value)
-}
-
-func (field *UnsafeStructField) Get(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("StructField.GetIndex argument 1", field.structType.ptrRType, objEFace.rtype)
-	value := field.UnsafeGet(objEFace.data)
-	return packEFace(field.ptrRType, value)
-}
-
-func (field *UnsafeStructField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer {
-	return add(obj, field.StructField.Offset, "same as non-reflect &v.field")
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_iface.go b/vendor/github.com/modern-go/reflect2/unsafe_iface.go
deleted file mode 100644
index b60195533..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_iface.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type iface struct {
-	itab *itab
-	data unsafe.Pointer
-}
-
-type itab struct {
-	ignore unsafe.Pointer
-	rtype  unsafe.Pointer
-}
-
-func IFaceToEFace(ptr unsafe.Pointer) interface{} {
-	iface := (*iface)(ptr)
-	if iface.itab == nil {
-		return nil
-	}
-	return packEFace(iface.itab.rtype, iface.data)
-}
-
-type UnsafeIFaceType struct {
-	unsafeType
-}
-
-func newUnsafeIFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeIFaceType {
-	return &UnsafeIFaceType{
-		unsafeType: *newUnsafeType(cfg, type1),
-	}
-}
-
-func (type2 *UnsafeIFaceType) Indirect(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIndirect(objEFace.data)
-}
-
-func (type2 *UnsafeIFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
-	return IFaceToEFace(ptr)
-}
-
-func (type2 *UnsafeIFaceType) IsNil(obj interface{}) bool {
-	if obj == nil {
-		return true
-	}
-	objEFace := unpackEFace(obj)
-	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIsNil(objEFace.data)
-}
-
-func (type2 *UnsafeIFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
-	if ptr == nil {
-		return true
-	}
-	iface := (*iface)(ptr)
-	if iface.itab == nil {
-		return true
-	}
-	return false
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_link.go b/vendor/github.com/modern-go/reflect2/unsafe_link.go
deleted file mode 100644
index 57229c8db..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_link.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package reflect2
-
-import "unsafe"
-
-//go:linkname unsafe_New reflect.unsafe_New
-func unsafe_New(rtype unsafe.Pointer) unsafe.Pointer
-
-//go:linkname typedmemmove reflect.typedmemmove
-func typedmemmove(rtype unsafe.Pointer, dst, src unsafe.Pointer)
-
-//go:linkname unsafe_NewArray reflect.unsafe_NewArray
-func unsafe_NewArray(rtype unsafe.Pointer, length int) unsafe.Pointer
-
-// typedslicecopy copies a slice of elemType values from src to dst,
-// returning the number of elements copied.
-//go:linkname typedslicecopy reflect.typedslicecopy
-//go:noescape
-func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int
-
-//go:linkname mapassign reflect.mapassign
-//go:noescape
-func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer)
-
-//go:linkname mapaccess reflect.mapaccess
-//go:noescape
-func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
-
-// m escapes into the return value, but the caller of mapiterinit
-// doesn't let the return value escape.
-//go:noescape
-//go:linkname mapiterinit reflect.mapiterinit
-func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) *hiter
-
-//go:noescape
-//go:linkname mapiternext reflect.mapiternext
-func mapiternext(it *hiter)
-
-//go:linkname ifaceE2I reflect.ifaceE2I
-func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer)
-
-// A hash iteration structure.
-// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate
-// the layout of this structure.
-type hiter struct {
-	key   unsafe.Pointer // Must be in first position.  Write nil to indicate iteration end (see cmd/internal/gc/range.go).
-	value unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go).
-	// rest fields are ignored
-}
-
-// add returns p+x.
-//
-// The whySafe string is ignored, so that the function still inlines
-// as efficiently as p+x, but all call sites should use the string to
-// record why the addition is safe, which is to say why the addition
-// does not cause x to advance to the very end of p's allocation
-// and therefore point incorrectly at the next block in memory.
-func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
-	return unsafe.Pointer(uintptr(p) + x)
-}
-
-// arrayAt returns the i-th element of p,
-// an array whose elements are eltSize bytes wide.
-// The array pointed at by p must have at least i+1 elements:
-// it is invalid (but impossible to check here) to pass i >= len,
-// because then the result will point outside the array.
-// whySafe must explain why i < len. (Passing "i < len" is fine;
-// the benefit is to surface this assumption at the call site.)
-func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
-	return add(p, uintptr(i)*eltSize, "i < len")
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_map.go b/vendor/github.com/modern-go/reflect2/unsafe_map.go
deleted file mode 100644
index f2e76e6bb..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_map.go
+++ /dev/null
@@ -1,138 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type UnsafeMapType struct {
-	unsafeType
-	pKeyRType  unsafe.Pointer
-	pElemRType unsafe.Pointer
-}
-
-func newUnsafeMapType(cfg *frozenConfig, type1 reflect.Type) MapType {
-	return &UnsafeMapType{
-		unsafeType: *newUnsafeType(cfg, type1),
-		pKeyRType:  unpackEFace(reflect.PtrTo(type1.Key())).data,
-		pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data,
-	}
-}
-
-func (type2 *UnsafeMapType) IsNil(obj interface{}) bool {
-	if obj == nil {
-		return true
-	}
-	objEFace := unpackEFace(obj)
-	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIsNil(objEFace.data)
-}
-
-func (type2 *UnsafeMapType) UnsafeIsNil(ptr unsafe.Pointer) bool {
-	if ptr == nil {
-		return true
-	}
-	return *(*unsafe.Pointer)(ptr) == nil
-}
-
-func (type2 *UnsafeMapType) LikePtr() bool {
-	return true
-}
-
-func (type2 *UnsafeMapType) Indirect(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("MapType.Indirect argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIndirect(objEFace.data)
-}
-
-func (type2 *UnsafeMapType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
-	return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
-}
-
-func (type2 *UnsafeMapType) Key() Type {
-	return type2.cfg.Type2(type2.Type.Key())
-}
-
-func (type2 *UnsafeMapType) MakeMap(cap int) interface{} {
-	return packEFace(type2.ptrRType, type2.UnsafeMakeMap(cap))
-}
-
-func (type2 *UnsafeMapType) UnsafeMakeMap(cap int) unsafe.Pointer {
-	m := makeMapWithSize(type2.rtype, cap)
-	return unsafe.Pointer(&m)
-}
-
-func (type2 *UnsafeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("MapType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
-	keyEFace := unpackEFace(key)
-	assertType("MapType.SetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
-	elemEFace := unpackEFace(elem)
-	assertType("MapType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
-	type2.UnsafeSetIndex(objEFace.data, keyEFace.data, elemEFace.data)
-}
-
-func (type2 *UnsafeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) {
-	mapassign(type2.rtype, *(*unsafe.Pointer)(obj), key, elem)
-}
-
-func (type2 *UnsafeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) {
-	objEFace := unpackEFace(obj)
-	assertType("MapType.TryGetIndex argument 1", type2.ptrRType, objEFace.rtype)
-	keyEFace := unpackEFace(key)
-	assertType("MapType.TryGetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
-	elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data)
-	if elemPtr == nil {
-		return nil, false
-	}
-	return packEFace(type2.pElemRType, elemPtr), true
-}
-
-func (type2 *UnsafeMapType) GetIndex(obj interface{}, key interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("MapType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
-	keyEFace := unpackEFace(key)
-	assertType("MapType.GetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
-	elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data)
-	return packEFace(type2.pElemRType, elemPtr)
-}
-
-func (type2 *UnsafeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer {
-	return mapaccess(type2.rtype, *(*unsafe.Pointer)(obj), key)
-}
-
-func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator {
-	objEFace := unpackEFace(obj)
-	assertType("MapType.Iterate argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIterate(objEFace.data)
-}
-
-func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
-	return &UnsafeMapIterator{
-		hiter:      mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)),
-		pKeyRType:  type2.pKeyRType,
-		pElemRType: type2.pElemRType,
-	}
-}
-
-type UnsafeMapIterator struct {
-	*hiter
-	pKeyRType  unsafe.Pointer
-	pElemRType unsafe.Pointer
-}
-
-func (iter *UnsafeMapIterator) HasNext() bool {
-	return iter.key != nil
-}
-
-func (iter *UnsafeMapIterator) Next() (interface{}, interface{}) {
-	key, elem := iter.UnsafeNext()
-	return packEFace(iter.pKeyRType, key), packEFace(iter.pElemRType, elem)
-}
-
-func (iter *UnsafeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) {
-	key := iter.key
-	elem := iter.value
-	mapiternext(iter.hiter)
-	return key, elem
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_ptr.go b/vendor/github.com/modern-go/reflect2/unsafe_ptr.go
deleted file mode 100644
index 8e5ec9cf4..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_ptr.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type UnsafePtrType struct {
-	unsafeType
-}
-
-func newUnsafePtrType(cfg *frozenConfig, type1 reflect.Type) *UnsafePtrType {
-	return &UnsafePtrType{
-		unsafeType: *newUnsafeType(cfg, type1),
-	}
-}
-
-func (type2 *UnsafePtrType) IsNil(obj interface{}) bool {
-	if obj == nil {
-		return true
-	}
-	objEFace := unpackEFace(obj)
-	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIsNil(objEFace.data)
-}
-
-func (type2 *UnsafePtrType) UnsafeIsNil(ptr unsafe.Pointer) bool {
-	if ptr == nil {
-		return true
-	}
-	return *(*unsafe.Pointer)(ptr) == nil
-}
-
-func (type2 *UnsafePtrType) LikePtr() bool {
-	return true
-}
-
-func (type2 *UnsafePtrType) Indirect(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIndirect(objEFace.data)
-}
-
-func (type2 *UnsafePtrType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
-	return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_slice.go b/vendor/github.com/modern-go/reflect2/unsafe_slice.go
deleted file mode 100644
index 1c6d876c7..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_slice.go
+++ /dev/null
@@ -1,177 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-// sliceHeader is a safe version of SliceHeader used within this package.
-type sliceHeader struct {
-	Data unsafe.Pointer
-	Len  int
-	Cap  int
-}
-
-type UnsafeSliceType struct {
-	unsafeType
-	elemRType  unsafe.Pointer
-	pElemRType unsafe.Pointer
-	elemSize   uintptr
-}
-
-func newUnsafeSliceType(cfg *frozenConfig, type1 reflect.Type) SliceType {
-	elemType := type1.Elem()
-	return &UnsafeSliceType{
-		unsafeType: *newUnsafeType(cfg, type1),
-		pElemRType: unpackEFace(reflect.PtrTo(elemType)).data,
-		elemRType:  unpackEFace(elemType).data,
-		elemSize:   elemType.Size(),
-	}
-}
-
-func (type2 *UnsafeSliceType) Set(obj interface{}, val interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype)
-	valEFace := unpackEFace(val)
-	assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype)
-	type2.UnsafeSet(objEFace.data, valEFace.data)
-}
-
-func (type2 *UnsafeSliceType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
-	*(*sliceHeader)(ptr) = *(*sliceHeader)(val)
-}
-
-func (type2 *UnsafeSliceType) IsNil(obj interface{}) bool {
-	if obj == nil {
-		return true
-	}
-	objEFace := unpackEFace(obj)
-	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIsNil(objEFace.data)
-}
-
-func (type2 *UnsafeSliceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
-	if ptr == nil {
-		return true
-	}
-	return (*sliceHeader)(ptr).Data == nil
-}
-
-func (type2 *UnsafeSliceType) SetNil(obj interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("SliceType.SetNil argument 1", type2.ptrRType, objEFace.rtype)
-	type2.UnsafeSetNil(objEFace.data)
-}
-
-func (type2 *UnsafeSliceType) UnsafeSetNil(ptr unsafe.Pointer) {
-	header := (*sliceHeader)(ptr)
-	header.Len = 0
-	header.Cap = 0
-	header.Data = nil
-}
-
-func (type2 *UnsafeSliceType) MakeSlice(length int, cap int) interface{} {
-	return packEFace(type2.ptrRType, type2.UnsafeMakeSlice(length, cap))
-}
-
-func (type2 *UnsafeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer {
-	header := &sliceHeader{unsafe_NewArray(type2.elemRType, cap), length, cap}
-	return unsafe.Pointer(header)
-}
-
-func (type2 *UnsafeSliceType) LengthOf(obj interface{}) int {
-	objEFace := unpackEFace(obj)
-	assertType("SliceType.Len argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeLengthOf(objEFace.data)
-}
-
-func (type2 *UnsafeSliceType) UnsafeLengthOf(obj unsafe.Pointer) int {
-	header := (*sliceHeader)(obj)
-	return header.Len
-}
-
-func (type2 *UnsafeSliceType) SetIndex(obj interface{}, index int, elem interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("SliceType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
-	elemEFace := unpackEFace(elem)
-	assertType("SliceType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
-	type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data)
-}
-
-func (type2 *UnsafeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) {
-	header := (*sliceHeader)(obj)
-	elemPtr := arrayAt(header.Data, index, type2.elemSize, "i < s.Len")
-	typedmemmove(type2.elemRType, elemPtr, elem)
-}
-
-func (type2 *UnsafeSliceType) GetIndex(obj interface{}, index int) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("SliceType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
-	elemPtr := type2.UnsafeGetIndex(objEFace.data, index)
-	return packEFace(type2.pElemRType, elemPtr)
-}
-
-func (type2 *UnsafeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer {
-	header := (*sliceHeader)(obj)
-	return arrayAt(header.Data, index, type2.elemSize, "i < s.Len")
-}
-
-func (type2 *UnsafeSliceType) Append(obj interface{}, elem interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("SliceType.Append argument 1", type2.ptrRType, objEFace.rtype)
-	elemEFace := unpackEFace(elem)
-	assertType("SliceType.Append argument 2", type2.pElemRType, elemEFace.rtype)
-	type2.UnsafeAppend(objEFace.data, elemEFace.data)
-}
-
-func (type2 *UnsafeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) {
-	header := (*sliceHeader)(obj)
-	oldLen := header.Len
-	type2.UnsafeGrow(obj, oldLen+1)
-	type2.UnsafeSetIndex(obj, oldLen, elem)
-}
-
-func (type2 *UnsafeSliceType) Cap(obj interface{}) int {
-	objEFace := unpackEFace(obj)
-	assertType("SliceType.Cap argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeCap(objEFace.data)
-}
-
-func (type2 *UnsafeSliceType) UnsafeCap(ptr unsafe.Pointer) int {
-	return (*sliceHeader)(ptr).Cap
-}
-
-func (type2 *UnsafeSliceType) Grow(obj interface{}, newLength int) {
-	objEFace := unpackEFace(obj)
-	assertType("SliceType.Grow argument 1", type2.ptrRType, objEFace.rtype)
-	type2.UnsafeGrow(objEFace.data, newLength)
-}
-
-func (type2 *UnsafeSliceType) UnsafeGrow(obj unsafe.Pointer, newLength int) {
-	header := (*sliceHeader)(obj)
-	if newLength <= header.Cap {
-		header.Len = newLength
-		return
-	}
-	newCap := calcNewCap(header.Cap, newLength)
-	newHeader := (*sliceHeader)(type2.UnsafeMakeSlice(header.Len, newCap))
-	typedslicecopy(type2.elemRType, *newHeader, *header)
-	header.Data = newHeader.Data
-	header.Cap = newHeader.Cap
-	header.Len = newLength
-}
-
-func calcNewCap(cap int, expectedCap int) int {
-	if cap == 0 {
-		cap = expectedCap
-	} else {
-		for cap < expectedCap {
-			if cap < 1024 {
-				cap += cap
-			} else {
-				cap += cap / 4
-			}
-		}
-	}
-	return cap
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_struct.go b/vendor/github.com/modern-go/reflect2/unsafe_struct.go
deleted file mode 100644
index 804d91663..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_struct.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type UnsafeStructType struct {
-	unsafeType
-	likePtr bool
-}
-
-func newUnsafeStructType(cfg *frozenConfig, type1 reflect.Type) *UnsafeStructType {
-	return &UnsafeStructType{
-		unsafeType: *newUnsafeType(cfg, type1),
-		likePtr:    likePtrType(type1),
-	}
-}
-
-func (type2 *UnsafeStructType) LikePtr() bool {
-	return type2.likePtr
-}
-
-func (type2 *UnsafeStructType) Indirect(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIndirect(objEFace.data)
-}
-
-func (type2 *UnsafeStructType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
-	if type2.likePtr {
-		return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
-	}
-	return packEFace(type2.rtype, ptr)
-}
-
-func (type2 *UnsafeStructType) FieldByName(name string) StructField {
-	structField, found := type2.Type.FieldByName(name)
-	if !found {
-		return nil
-	}
-	return newUnsafeStructField(type2, structField)
-}
-
-func (type2 *UnsafeStructType) Field(i int) StructField {
-	return newUnsafeStructField(type2, type2.Type.Field(i))
-}
-
-func (type2 *UnsafeStructType) FieldByIndex(index []int) StructField {
-	return newUnsafeStructField(type2, type2.Type.FieldByIndex(index))
-}
-
-func (type2 *UnsafeStructType) FieldByNameFunc(match func(string) bool) StructField {
-	structField, found := type2.Type.FieldByNameFunc(match)
-	if !found {
-		panic("field match condition not found in " + type2.Type.String())
-	}
-	return newUnsafeStructField(type2, structField)
-}
diff --git a/vendor/github.com/modern-go/reflect2/unsafe_type.go b/vendor/github.com/modern-go/reflect2/unsafe_type.go
deleted file mode 100644
index 13941716c..000000000
--- a/vendor/github.com/modern-go/reflect2/unsafe_type.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package reflect2
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-type unsafeType struct {
-	safeType
-	rtype    unsafe.Pointer
-	ptrRType unsafe.Pointer
-}
-
-func newUnsafeType(cfg *frozenConfig, type1 reflect.Type) *unsafeType {
-	return &unsafeType{
-		safeType: safeType{
-			Type: type1,
-			cfg:  cfg,
-		},
-		rtype:    unpackEFace(type1).data,
-		ptrRType: unpackEFace(reflect.PtrTo(type1)).data,
-	}
-}
-
-func (type2 *unsafeType) Set(obj interface{}, val interface{}) {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype)
-	valEFace := unpackEFace(val)
-	assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype)
-	type2.UnsafeSet(objEFace.data, valEFace.data)
-}
-
-func (type2 *unsafeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
-	typedmemmove(type2.rtype, ptr, val)
-}
-
-func (type2 *unsafeType) IsNil(obj interface{}) bool {
-	objEFace := unpackEFace(obj)
-	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIsNil(objEFace.data)
-}
-
-func (type2 *unsafeType) UnsafeIsNil(ptr unsafe.Pointer) bool {
-	return ptr == nil
-}
-
-func (type2 *unsafeType) UnsafeNew() unsafe.Pointer {
-	return unsafe_New(type2.rtype)
-}
-
-func (type2 *unsafeType) New() interface{} {
-	return packEFace(type2.ptrRType, type2.UnsafeNew())
-}
-
-func (type2 *unsafeType) PackEFace(ptr unsafe.Pointer) interface{} {
-	return packEFace(type2.ptrRType, ptr)
-}
-
-func (type2 *unsafeType) RType() uintptr {
-	return uintptr(type2.rtype)
-}
-
-func (type2 *unsafeType) Indirect(obj interface{}) interface{} {
-	objEFace := unpackEFace(obj)
-	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
-	return type2.UnsafeIndirect(objEFace.data)
-}
-
-func (type2 *unsafeType) UnsafeIndirect(obj unsafe.Pointer) interface{} {
-	return packEFace(type2.rtype, obj)
-}
-
-func (type2 *unsafeType) LikePtr() bool {
-	return false
-}
-
-func assertType(where string, expectRType unsafe.Pointer, actualRType unsafe.Pointer) {
-	if expectRType != actualRType {
-		expectType := reflect.TypeOf(0)
-		(*iface)(unsafe.Pointer(&expectType)).data = expectRType
-		actualType := reflect.TypeOf(0)
-		(*iface)(unsafe.Pointer(&actualType)).data = actualRType
-		panic(where + ": expect " + expectType.String() + ", actual " + actualType.String())
-	}
-}
diff --git a/vendor/github.com/oleksandr/bonjour/.gitignore b/vendor/github.com/oleksandr/bonjour/.gitignore
new file mode 100644
index 000000000..daf913b1b
--- /dev/null
+++ b/vendor/github.com/oleksandr/bonjour/.gitignore
@@ -0,0 +1,24 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
diff --git a/vendor/github.com/oleksandr/bonjour/README.md b/vendor/github.com/oleksandr/bonjour/README.md
new file mode 100644
index 000000000..796708e3d
--- /dev/null
+++ b/vendor/github.com/oleksandr/bonjour/README.md
@@ -0,0 +1,165 @@
+bonjour
+====
+
+This is a simple Multicast DNS-SD (Apple Bonjour) library written in Golang. You can use it to discover services in the LAN. Pay attention to the infrastructure you are planning to use it (clouds or shared infrastructures usually prevent mDNS from functioning). But it should work in the most office, home and private environments.
+
+**IMPORTANT**: It does NOT pretend to be a full & valid implementation of the RFC 6762 & RFC 6763, but it fulfils the requirements of its authors (we just needed service discovery in the LAN environment for our IoT products). The registration code needs a lot of improvements. This code was not tested for Bonjour conformance but have been manually verified to be working using built-in OSX utility `/usr/bin/dns-sd`.
+
+Detailed documentation: [![GoDoc](https://godoc.org/github.com/oleksandr/bonjour?status.svg)](https://godoc.org/github.com/oleksandr/bonjour)
+
+
+##Browsing available services in your local network
+
+Here is an example how to browse services by their type:
+
+```
+package main
+
+import (
+    "log"
+    "os"
+    "time"
+
+    "github.com/oleksandr/bonjour"
+)
+
+func main() {
+    resolver, err := bonjour.NewResolver(nil)
+    if err != nil {
+        log.Println("Failed to initialize resolver:", err.Error())
+        os.Exit(1)
+    }
+
+    results := make(chan *bonjour.ServiceEntry)
+
+    go func(results chan *bonjour.ServiceEntry, exitCh chan<- bool) {
+        for e := range results {
+            log.Printf("%s", e.Instance)
+            exitCh <- true
+            time.Sleep(1e9)
+            os.Exit(0)
+        }
+    }(results, resolver.Exit)
+
+    err = resolver.Browse("_foobar._tcp", "local.", results)
+    if err != nil {
+        log.Println("Failed to browse:", err.Error())
+    }
+
+    select {}
+}
+```
+
+##Doing a lookup of a specific service instance
+
+Here is an example of looking up service by service instance name:
+
+```
+package main
+
+import (
+    "log"
+    "os"
+    "time"
+
+    "github.com/oleksandr/bonjour"
+)
+
+func main() {
+    resolver, err := bonjour.NewResolver(nil)
+    if err != nil {
+        log.Println("Failed to initialize resolver:", err.Error())
+        os.Exit(1)
+    }
+
+    results := make(chan *bonjour.ServiceEntry)
+
+    go func(results chan *bonjour.ServiceEntry, exitCh chan<- bool) {
+        for e := range results {
+            log.Printf("%s", e.Instance)
+            exitCh <- true
+            time.Sleep(1e9)
+            os.Exit(0)
+        }
+    }(results, resolver.Exit)
+
+    err = resolver.Lookup("DEMO", "_foobar._tcp", "", results)
+    if err != nil {
+        log.Println("Failed to browse:", err.Error())
+    }
+
+    select {}
+}
+```
+
+
+##Registering a service
+
+Registering a service is as simple as the following:
+
+```
+package main
+
+import (
+    "log"
+    "os"
+    "os/signal"
+    "time"
+
+    "github.com/oleksandr/bonjour"
+)
+
+func main() {
+    // Run registration (blocking call)
+    s, err := bonjour.Register("Foo Service", "_foobar._tcp", "", 9999, []string{"txtv=1", "app=test"}, nil)
+    if err != nil {
+        log.Fatalln(err.Error())
+    }
+
+    // Ctrl+C handling
+    handler := make(chan os.Signal, 1)
+    signal.Notify(handler, os.Interrupt)
+    for sig := range handler {
+        if sig == os.Interrupt {
+            s.Shutdown()
+            time.Sleep(1e9)
+            break
+        }
+    }
+}
+```
+
+
+##Registering a service proxy (manually specifying host/ip and avoiding lookups)
+
+```
+package main
+
+import (
+    "log"
+    "os"
+    "os/signal"
+    "time"
+
+    "github.com/oleksandr/bonjour"
+)
+
+func main() {
+    // Run registration (blocking call)
+    s, err := bonjour.RegisterProxy("Proxy Service", "_foobar._tcp", "", 9999, "octopus", "10.0.0.111", []string{"txtv=1", "app=test"}, nil)
+    if err != nil {
+        log.Fatalln(err.Error())
+    }
+
+    // Ctrl+C handling
+    handler := make(chan os.Signal, 1)
+    signal.Notify(handler, os.Interrupt)
+    for sig := range handler {
+        if sig == os.Interrupt {
+            s.Shutdown()
+            time.Sleep(1e9)
+            break
+        }
+    }
+}
+```
\ No newline at end of file
diff --git a/vendor/github.com/oxtoacart/bpool/README.md b/vendor/github.com/oxtoacart/bpool/README.md
new file mode 100644
index 000000000..9acf3f928
--- /dev/null
+++ b/vendor/github.com/oxtoacart/bpool/README.md
@@ -0,0 +1,65 @@
+# bpool [![GoDoc](https://godoc.org/github.com/oxtoacart/bpool?status.png)](https://godoc.org/github.com/oxtoacart/bpool)
+
+Package bpool implements leaky pools of byte arrays and Buffers as bounded channels. 
+It is based on the leaky buffer example from the Effective Go documentation: http://golang.org/doc/effective_go.html#leaky_buffer
+
+bpool provides the following pool types:
+
+* [bpool.BufferPool](https://godoc.org/github.com/oxtoacart/bpool#BufferPool)
+  which provides a fixed-size pool of
+  [bytes.Buffers](http://golang.org/pkg/bytes/#Buffer).
+* [bpool.BytePool](https://godoc.org/github.com/oxtoacart/bpool#BytePool) which
+  provides a fixed-size pool of `[]byte` slices with a pre-set width (length).
+* [bpool.SizedBufferPool](https://godoc.org/github.com/oxtoacart/bpool#SizedBufferPool), 
+  which is an alternative to `bpool.BufferPool` that pre-sizes the capacity of
+  buffers issued from the pool and discards buffers that have grown too large
+  upon return.
+
+A common use case for this package is to use buffers to execute HTML templates
+against (via ExecuteTemplate) or encode JSON into (via json.NewEncoder). This
+allows you to catch any rendering or marshalling errors prior to writing to a
+`http.ResponseWriter`, which helps to avoid writing incomplete or malformed data
+to the response.
+
+## Install
+
+`go get github.com/oxtoacart/bpool`
+
+## Documentation
+
+See [godoc.org](http://godoc.org/github.com/oxtoacart/bpool) or use `godoc github.com/oxtoacart/bpool`
+
+## Example
+
+Here's a quick example for using `bpool.BufferPool`. We create a pool of the
+desired size, call the `Get()` method to obtain a buffer for use, and call
+`Put(buf)` to return the buffer to the pool.
+
+```go
+
+var bufpool *bpool.BufferPool
+
+func main() {
+
+    bufpool = bpool.NewBufferPool(48)
+
+}
+
+func someFunction() error {
+
+     // Get a buffer from the pool
+     buf := bufpool.Get()
+     ...
+     ...
+     ...
+     // Return the buffer to the pool
+     bufpool.Put(buf)
+
+     return nil
+}
+```
+
+## License
+
+Apache 2.0 Licensed. See the LICENSE file for details.
+
diff --git a/vendor/github.com/pkg/errors/.gitignore b/vendor/github.com/pkg/errors/.gitignore
new file mode 100644
index 000000000..daf913b1b
--- /dev/null
+++ b/vendor/github.com/pkg/errors/.gitignore
@@ -0,0 +1,24 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
diff --git a/vendor/github.com/pkg/errors/.travis.yml b/vendor/github.com/pkg/errors/.travis.yml
new file mode 100644
index 000000000..588ceca18
--- /dev/null
+++ b/vendor/github.com/pkg/errors/.travis.yml
@@ -0,0 +1,11 @@
+language: go
+go_import_path: github.com/pkg/errors
+go:
+  - 1.4.3
+  - 1.5.4
+  - 1.6.2
+  - 1.7.1
+  - tip
+
+script:
+  - go test -v ./...
diff --git a/vendor/github.com/pkg/errors/README.md b/vendor/github.com/pkg/errors/README.md
new file mode 100644
index 000000000..273db3c98
--- /dev/null
+++ b/vendor/github.com/pkg/errors/README.md
@@ -0,0 +1,52 @@
+# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors)
+
+Package errors provides simple error handling primitives.
+
+`go get github.com/pkg/errors`
+
+The traditional error handling idiom in Go is roughly akin to
+```go
+if err != nil {
+        return err
+}
+```
+which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.
+
+## Adding context to an error
+
+The errors.Wrap function returns a new error that adds context to the original error. For example
+```go
+_, err := ioutil.ReadAll(r)
+if err != nil {
+        return errors.Wrap(err, "read failed")
+}
+```
+## Retrieving the cause of an error
+
+Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.
+```go
+type causer interface {
+        Cause() error
+}
+```
+`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:
+```go
+switch err := errors.Cause(err).(type) {
+case *MyError:
+        // handle specifically
+default:
+        // unknown error
+}
+```
+
+[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
+
+## Contributing
+
+We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high.
+
+Before proposing a change, please discuss your change by raising an issue.
+
+## Licence
+
+BSD-2-Clause
diff --git a/vendor/github.com/pkg/errors/appveyor.yml b/vendor/github.com/pkg/errors/appveyor.yml
new file mode 100644
index 000000000..a932eade0
--- /dev/null
+++ b/vendor/github.com/pkg/errors/appveyor.yml
@@ -0,0 +1,32 @@
+version: build-{build}.{branch}
+
+clone_folder: C:\gopath\src\github.com\pkg\errors
+shallow_clone: true # for startup speed
+
+environment:
+  GOPATH: C:\gopath
+
+platform:
+  - x64
+
+# http://www.appveyor.com/docs/installed-software
+install:
+  # some helpful output for debugging builds
+  - go version
+  - go env
+  # pre-installed MinGW at C:\MinGW is 32bit only
+  # but MSYS2 at C:\msys64 has mingw64
+  - set PATH=C:\msys64\mingw64\bin;%PATH%
+  - gcc --version
+  - g++ --version
+
+build_script:
+  - go install -v ./...
+
+test_script:
+  - set PATH=C:\gopath\bin;%PATH%
+  - go test -v ./...
+
+#artifacts:
+#  - path: '%GOPATH%\bin\*.exe'
+deploy: off
diff --git a/vendor/github.com/pkg/sftp/.gitignore b/vendor/github.com/pkg/sftp/.gitignore
new file mode 100644
index 000000000..e1ec837c3
--- /dev/null
+++ b/vendor/github.com/pkg/sftp/.gitignore
@@ -0,0 +1,7 @@
+.*.swo
+.*.swp
+
+server_standalone/server_standalone
+
+examples/*/id_rsa
+examples/*/id_rsa.pub
diff --git a/vendor/github.com/pkg/sftp/.travis.yml b/vendor/github.com/pkg/sftp/.travis.yml
new file mode 100644
index 000000000..44cd0e2ee
--- /dev/null
+++ b/vendor/github.com/pkg/sftp/.travis.yml
@@ -0,0 +1,38 @@
+language: go
+go_import_path: github.com/pkg/sftp
+
+# current and previous stable releases, plus tip
+# remember to exclude previous and tip for macs below
+go:
+  - 1.10.x
+  - 1.11.x
+  - tip
+
+os:
+  - linux
+  - osx
+
+matrix:
+  exclude:
+    - os: osx
+      go: 1.10.x
+    - os: osx
+      go: tip
+
+sudo: false
+
+addons:
+  ssh_known_hosts:
+      - bitbucket.org
+
+install:
+  - go get -t -v ./...
+  - ssh-keygen -t rsa -q -P "" -f $HOME/.ssh/id_rsa
+
+script:
+  - go test -integration -v ./...
+  - go test -testserver -v ./...
+  - go test -integration -testserver -v ./...
+  - go test -race -integration -v ./...
+  - go test -race -testserver -v ./...
+  - go test -race -integration -testserver -v ./...
diff --git a/vendor/github.com/pkg/sftp/README.md b/vendor/github.com/pkg/sftp/README.md
new file mode 100644
index 000000000..1fb700c41
--- /dev/null
+++ b/vendor/github.com/pkg/sftp/README.md
@@ -0,0 +1,44 @@
+sftp
+----
+
+The `sftp` package provides support for file system operations on remote ssh
+servers using the SFTP subsystem. It also implements an SFTP server for serving
+files from the filesystem.
+
+[![UNIX Build Status](https://travis-ci.org/pkg/sftp.svg?branch=master)](https://travis-ci.org/pkg/sftp) [![GoDoc](http://godoc.org/github.com/pkg/sftp?status.svg)](http://godoc.org/github.com/pkg/sftp)
+
+usage and examples
+------------------
+
+See [godoc.org/github.com/pkg/sftp](http://godoc.org/github.com/pkg/sftp) for
+examples and usage.
+
+The basic operation of the package mirrors the facilities of the
+[os](http://golang.org/pkg/os) package.
+
+The Walker interface for directory traversal is heavily inspired by Keith
+Rarick's [fs](http://godoc.org/github.com/kr/fs) package.
+
+roadmap
+-------
+
+ * There is way too much duplication in the Client methods. If there was an
+   unmarshal(interface{}) method this would reduce a heap of the duplication.
+
+contributing
+------------
+
+We welcome pull requests, bug fixes and issue reports.
+
+Before proposing a large change, first please discuss your change by raising an
+issue.
+
+For API/code bugs, please include a small, self contained code example to
+reproduce the issue. For pull requests, remember test coverage.
+
+We try to handle issues and pull requests with a 0 open philosophy. That means
+we will try to address the submission as soon as possible and will work toward
+a resolution. If progress can no longer be made (eg. unreproducible bug) or
+stops (eg. unresponsive submitter), we will close the bug.
+
+Thanks.
diff --git a/vendor/github.com/pkg/sftp/request-readme.md b/vendor/github.com/pkg/sftp/request-readme.md
new file mode 100644
index 000000000..f887274dc
--- /dev/null
+++ b/vendor/github.com/pkg/sftp/request-readme.md
@@ -0,0 +1,53 @@
+# Request Based SFTP API
+
+The request based API allows for custom backends in a way similar to the http
+package. In order to create a backend you need to implement 4 handler
+interfaces; one for reading, one for writing, one for misc commands and one for
+listing files. Each has 1 required method and in each case those methods take
+the Request as the only parameter and they each return something different.
+These 4 interfaces are enough to handle all the SFTP traffic in a simplified
+manner.
+
+The Request structure has 5 public fields which you will deal with.
+
+- Method (string) - string name of incoming call
+- Filepath (string) - POSIX path of file to act on
+- Flags (uint32) - 32bit bitmask value of file open/create flags
+- Attrs ([]byte) - byte string of file attribute data
+- Target (string) - target path for renames and sym-links
+
+Below are the methods and a brief description of what they need to do.
+
+### Fileread(*Request) (io.Reader, error)
+
+Handler for "Get" method and returns an io.Reader for the file which the server
+then sends to the client.
+
+### Filewrite(*Request) (io.Writer, error)
+
+Handler for "Put" method and returns an io.Writer for the file which the server
+then writes the uploaded file to. The file opening "pflags" are currently
+preserved in the Request.Flags field as a 32bit bitmask value. See the [SFTP
+spec](https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.3) for
+details.
+
+###    Filecmd(*Request) error
+
+Handles "SetStat", "Rename", "Rmdir", "Mkdir"  and "Symlink" methods. Makes the
+appropriate changes and returns nil for success or an filesystem like error
+(eg. os.ErrNotExist). The attributes are currently propagated in their raw form
+([]byte) and will need to be unmarshalled to be useful. See the respond method
+on sshFxpSetstatPacket for example of you might want to do this.
+
+### Fileinfo(*Request) ([]os.FileInfo, error)
+
+Handles "List", "Stat", "Readlink" methods. Gathers/creates FileInfo structs
+with the data on the files and returns in a list (list of 1 for Stat and
+Readlink).
+
+
+## TODO
+
+- Add support for API users to see trace/debugging info of what is going on
+inside SFTP server.
+- Unmarshal the file attributes into a structure on the Request object.
diff --git a/vendor/github.com/sfreiberg/simplessh/README.md b/vendor/github.com/sfreiberg/simplessh/README.md
new file mode 100644
index 000000000..086b0c88d
--- /dev/null
+++ b/vendor/github.com/sfreiberg/simplessh/README.md
@@ -0,0 +1,47 @@
+# simplessh
+[![GoDoc](https://godoc.org/github.com/sfreiberg/simplessh?status.png)](https://godoc.org/github.com/sfreiberg/simplessh)
+
+SimpleSSH is a simple wrapper around go ssh and sftp libraries.
+
+## Features
+* Multiple authentication methods (password, private key and ssh-agent)
+* Sudo support
+* Simple file upload/download support
+
+## Installation
+`go get github.com/sfreiberg/simplessh`
+
+## Example
+
+```
+package main
+
+import (
+	"fmt"
+	
+	"github.com/sfreiberg/simplessh"
+)
+
+func main() {
+	/*
+		Leave privKeyPath empty to use $HOME/.ssh/id_rsa.
+		If username is blank simplessh will attempt to use the current user.
+	*/
+	client, err := simplessh.ConnectWithKeyFile("localhost:22", "root", "/home/user/.ssh/id_rsa")
+	if err != nil {
+		panic(err)
+	}
+	defer client.Close()
+
+	output, err := client.Exec("uptime")
+	if err != nil {
+		panic(err)
+	}
+
+	fmt.Printf("Uptime: %s\n", output)
+}
+
+```
+
+## License
+SimpleSSH is licensed under the MIT license.
\ No newline at end of file
diff --git a/vendor/github.com/ugorji/go/codec/0doc.go b/vendor/github.com/ugorji/go/codec/0doc.go
index b61a8180e..209f9ebad 100644
--- a/vendor/github.com/ugorji/go/codec/0doc.go
+++ b/vendor/github.com/ugorji/go/codec/0doc.go
@@ -1,10 +1,9 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 /*
-Package codec provides a
-High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
-for binc, msgpack, cbor, json.
+High Performance, Feature-Rich Idiomatic Go codec/encoding library for 
+binc, msgpack, cbor, json.
 
 Supported Serialization formats are:
 
@@ -12,17 +11,21 @@ Supported Serialization formats are:
   - binc:    http://github.com/ugorji/binc
   - cbor:    http://cbor.io http://tools.ietf.org/html/rfc7049
   - json:    http://json.org http://tools.ietf.org/html/rfc7159
-  - simple:
+  - simple: 
 
 To install:
 
     go get github.com/ugorji/go/codec
 
-This package will carefully use 'unsafe' for performance reasons in specific places.
-You can build without unsafe use by passing the safe or appengine tag
-i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
-go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
-go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
+This package understands the 'unsafe' tag, to allow using unsafe semantics:
+
+  - When decoding into a struct, you need to read the field name as a string 
+    so you can find the struct field it is mapped to.
+    Using `unsafe` will bypass the allocation and copying overhead of []byte->string conversion.
+
+To install using unsafe, pass the 'unsafe' tag:
+
+    go get -tags=unsafe github.com/ugorji/go/codec
 
 For detailed usage information, read the primer at http://ugorji.net/blog/go-codec-primer .
 
@@ -32,16 +35,12 @@ the standard library (ie json, xml, gob, etc).
 Rich Feature Set includes:
 
   - Simple but extremely powerful and feature-rich API
-  - Support for go1.4 and above, while selectively using newer APIs for later releases
-  - Excellent code coverage ( > 90% )
   - Very High Performance.
     Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
-  - Careful selected use of 'unsafe' for targeted performance gains.
-    100% mode exists where 'unsafe' is not used at all.
-  - Lock-free (sans mutex) concurrency for scaling to 100's of cores
-  - Coerce types where appropriate
-    e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
-  - Corner Cases:
+  - Multiple conversions:
+    Package coerces types where appropriate 
+    e.g. decode an int in the stream into a float, etc.
+  - Corner Cases: 
     Overflows, nil maps/slices, nil values in streams are handled correctly
   - Standard field renaming via tags
   - Support for omitting empty fields during an encoding
@@ -49,21 +48,15 @@ Rich Feature Set includes:
     (struct, slice, map, primitives, pointers, interface{}, etc)
   - Extensions to support efficient encoding/decoding of any named types
   - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
-  - Support IsZero() bool to determine if a value is a zero value.
-    Analogous to time.Time.IsZero() bool.
   - Decoding without a schema (into a interface{}).
     Includes Options to configure what specific map or slice type to use
     when decoding an encoded list or map into a nil interface{}
-  - Mapping a non-interface type to an interface, so we can decode appropriately
-    into any interface type with a correctly configured non-interface value.
   - Encode a struct as an array, and decode struct from an array in the data stream
-  - Option to encode struct keys as numbers (instead of strings)
-    (to support structured streams with fields encoded as numeric codes)
   - Comprehensive support for anonymous fields
   - Fast (no-reflection) encoding/decoding of common maps and slices
   - Code-generation for faster performance.
   - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
-  - Support indefinite-length formats to enable true streaming
+  - Support indefinite-length formats to enable true streaming 
     (for formats which support it e.g. json, cbor)
   - Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
     This mostly applies to maps, where iteration order is non-deterministic.
@@ -75,12 +68,12 @@ Rich Feature Set includes:
   - Encode/Decode from/to chan types (for iterative streaming support)
   - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
   - Provides a RPC Server and Client Codec for net/rpc communication protocol.
-  - Handle unique idiosyncrasies of codecs e.g.
-    - For messagepack, configure how ambiguities in handling raw bytes are resolved
-    - For messagepack, provide rpc server/client codec to support
+  - Handle unique idiosyncrasies of codecs e.g. 
+    - For messagepack, configure how ambiguities in handling raw bytes are resolved 
+    - For messagepack, provide rpc server/client codec to support 
       msgpack-rpc protocol defined at:
       https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
-
+  
 Extension Support
 
 Users can register a function to handle the encoding or decoding of
@@ -99,27 +92,6 @@ encoded as an empty map because it has no exported fields, while UUID
 would be encoded as a string. However, with extension support, you can
 encode any of these however you like.
 
-Custom Encoding and Decoding
-
-This package maintains symmetry in the encoding and decoding halfs.
-We determine how to encode or decode by walking this decision tree
-
-  - is type a codec.Selfer?
-  - is there an extension registered for the type?
-  - is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
-  - is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
-  - is format text-based, and type an encoding.TextMarshaler?
-  - else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
-
-This symmetry is important to reduce chances of issues happening because the
-encoding and decoding sides are out of sync e.g. decoded via very specific
-encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
-
-Consequently, if a type only defines one-half of the symmetry
-(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
-then that type doesn't satisfy the check and we will continue walking down the
-decision tree.
-
 RPC
 
 RPC Client and Server Codecs are implemented, so the codecs can be used
@@ -188,77 +160,40 @@ Sample usage model:
     //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
     client := rpc.NewClientWithCodec(rpcCodec)
 
-Running Tests
-
-To run tests, use the following:
-
-    go test
-
-To run the full suite of tests, use the following:
-
-    go test -tags alltests -run Suite
-
-You can run the tag 'safe' to run tests or build in safe mode. e.g.
-
-    go test -tags safe -run Json
-    go test -tags "alltests safe" -run Suite
-
-Running Benchmarks
-
-Please see http://github.com/ugorji/go-codec-bench .
-
-Caveats
-
-Struct fields matching the following are ignored during encoding and decoding
-    - struct tag value set to -
-    - func, complex numbers, unsafe pointers
-    - unexported and not embedded
-    - unexported and embedded and not struct kind
-    - unexported and embedded pointers (from go1.10)
-
-Every other field in a struct will be encoded/decoded.
-
-Embedded fields are encoded as if they exist in the top-level struct,
-with some caveats. See Encode documentation.
-
 */
 package codec
 
-// TODO:
-//   - For Go 1.11, when mid-stack inlining is enabled,
-//     we should use committed functions for writeXXX and readXXX calls.
-//     This involves uncommenting the methods for decReaderSwitch and encWriterSwitch
-//     and using those (decReaderSwitch and encWriterSwitch) in all handles
-//     instead of encWriter and decReader.
-//     The benefit is that, for the (En|De)coder over []byte, the encWriter/decReader
-//     will be inlined, giving a performance bump for that typical case.
-//     However, it will only  be inlined if mid-stack inlining is enabled,
-//     as we call panic to raise errors, and panic currently prevents inlining.
-//
-// PUNTED:
-//   - To make Handle comparable, make extHandle in BasicHandle a non-embedded pointer,
-//     and use overlay methods on *BasicHandle to call through to extHandle after initializing
-//     the "xh *extHandle" to point to a real slice.
+// Benefits of go-codec:
 //
-// BEFORE EACH RELEASE:
-//   - Look through and fix padding for each type, to eliminate false sharing
-//     - critical shared objects that are read many times
-//       TypeInfos
-//     - pooled objects:
-//       decNaked, decNakedContainers, codecFner, typeInfoLoadArray, 
-//     - small objects allocated independently, that we read/use much across threads:
-//       codecFn, typeInfo
-//     - Objects allocated independently and used a lot
-//       Decoder, Encoder,
-//       xxxHandle, xxxEncDriver, xxxDecDriver (xxx = json, msgpack, cbor, binc, simple)
-//     - In all above, arrange values modified together to be close to each other.
-//
-//     For all of these, either ensure that they occupy full cache lines,
-//     or ensure that the things just past the cache line boundary are hardly read/written
-//     e.g. JsonHandle.RawBytesExt - which is copied into json(En|De)cDriver at init
+//    - encoding/json always reads whole file into memory first.
+//      This makes it unsuitable for parsing very large files.
+//    - encoding/xml cannot parse into a map[string]interface{}
+//      I found this out on reading https://github.com/clbanning/mxj
+
+// TODO:
 //
-//     Occupying full cache lines means they occupy 8*N words (where N is an integer).
-//     Check this out by running: ./run.sh -z
-//     - look at those tagged ****, meaning they are not occupying full cache lines
-//     - look at those tagged <<<<, meaning they are larger than 32 words (something to watch)
-//   - Run "golint -min_confidence 0.81"
+//   - optimization for codecgen:
+//     if len of entity is <= 3 words, then support a value receiver for encode.
+//   - (En|De)coder should store an error when it occurs.
+//     Until reset, subsequent calls return that error that was stored.
+//     This means that free panics must go away.
+//     All errors must be raised through errorf method.
+//   - Decoding using a chan is good, but incurs concurrency costs.
+//     This is because there's no fast way to use a channel without it
+//     having to switch goroutines constantly.
+//     Callback pattern is still the best. Maybe consider supporting something like:
+//        type X struct {
+//             Name string
+//             Ys []Y
+//             Ys chan <- Y
+//             Ys func(Y) -> call this function for each entry
+//        }
+//    - Consider adding a isZeroer interface { isZero() bool }
+//      It is used within isEmpty, for omitEmpty support.
+//    - Consider making Handle used AS-IS within the encoding/decoding session.
+//      This means that we don't cache Handle information within the (En|De)coder,
+//      except we really need it at Reset(...)
+//    - Consider adding math/big support
+//    - Consider reducing the size of the generated functions:
+//      Maybe use one loop, and put the conditionals in the loop.
+//      for ... { if cLen > 0 { if j == cLen { break } } else if dd.CheckBreak() { break } }
diff --git a/vendor/github.com/ugorji/go/codec/README.md b/vendor/github.com/ugorji/go/codec/README.md
new file mode 100644
index 000000000..91cb3a27b
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/README.md
@@ -0,0 +1,148 @@
+# Codec
+
+High Performance, Feature-Rich Idiomatic Go codec/encoding library for
+binc, msgpack, cbor, json.
+
+Supported Serialization formats are:
+
+  - msgpack: https://github.com/msgpack/msgpack
+  - binc:    http://github.com/ugorji/binc
+  - cbor:    http://cbor.io http://tools.ietf.org/html/rfc7049
+  - json:    http://json.org http://tools.ietf.org/html/rfc7159
+  - simple: 
+
+To install:
+
+    go get github.com/ugorji/go/codec
+
+This package understands the `unsafe` tag, to allow using unsafe semantics:
+
+  - When decoding into a struct, you need to read the field name as a string 
+    so you can find the struct field it is mapped to.
+    Using `unsafe` will bypass the allocation and copying overhead of `[]byte->string` conversion.
+
+To use it, you must pass the `unsafe` tag during install:
+
+```
+go install -tags=unsafe github.com/ugorji/go/codec 
+```
+
+Online documentation: http://godoc.org/github.com/ugorji/go/codec  
+Detailed Usage/How-to Primer: http://ugorji.net/blog/go-codec-primer
+
+The idiomatic Go support is as seen in other encoding packages in
+the standard library (ie json, xml, gob, etc).
+
+Rich Feature Set includes:
+
+  - Simple but extremely powerful and feature-rich API
+  - Very High Performance.
+    Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
+  - Multiple conversions:
+    Package coerces types where appropriate 
+    e.g. decode an int in the stream into a float, etc.
+  - Corner Cases: 
+    Overflows, nil maps/slices, nil values in streams are handled correctly
+  - Standard field renaming via tags
+  - Support for omitting empty fields during an encoding
+  - Encoding from any value and decoding into pointer to any value
+    (struct, slice, map, primitives, pointers, interface{}, etc)
+  - Extensions to support efficient encoding/decoding of any named types
+  - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
+  - Decoding without a schema (into a interface{}).
+    Includes Options to configure what specific map or slice type to use
+    when decoding an encoded list or map into a nil interface{}
+  - Encode a struct as an array, and decode struct from an array in the data stream
+  - Comprehensive support for anonymous fields
+  - Fast (no-reflection) encoding/decoding of common maps and slices
+  - Code-generation for faster performance.
+  - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
+  - Support indefinite-length formats to enable true streaming 
+    (for formats which support it e.g. json, cbor)
+  - Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
+    This mostly applies to maps, where iteration order is non-deterministic.
+  - NIL in data stream decoded as zero value
+  - Never silently skip data when decoding.
+    User decides whether to return an error or silently skip data when keys or indexes
+    in the data stream do not map to fields in the struct.
+  - Encode/Decode from/to chan types (for iterative streaming support)
+  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
+  - Provides a RPC Server and Client Codec for net/rpc communication protocol.
+  - Handle unique idiosyncrasies of codecs e.g. 
+    - For messagepack, configure how ambiguities in handling raw bytes are resolved 
+    - For messagepack, provide rpc server/client codec to support
+      msgpack-rpc protocol defined at:
+      https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
+
+## Extension Support
+
+Users can register a function to handle the encoding or decoding of
+their custom types.
+
+There are no restrictions on what the custom type can be. Some examples:
+
+    type BisSet   []int
+    type BitSet64 uint64
+    type UUID     string
+    type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
+    type GifImage struct { ... }
+
+As an illustration, MyStructWithUnexportedFields would normally be
+encoded as an empty map because it has no exported fields, while UUID
+would be encoded as a string. However, with extension support, you can
+encode any of these however you like.
+
+## RPC
+
+RPC Client and Server Codecs are implemented, so the codecs can be used
+with the standard net/rpc package.
+
+## Usage
+
+Typical usage model:
+
+    // create and configure Handle
+    var (
+      bh codec.BincHandle
+      mh codec.MsgpackHandle
+      ch codec.CborHandle
+    )
+
+    mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
+
+    // configure extensions
+    // e.g. for msgpack, define functions and enable Time support for tag 1
+    // mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
+
+    // create and use decoder/encoder
+    var (
+      r io.Reader
+      w io.Writer
+      b []byte
+      h = &bh // or mh to use msgpack
+    )
+
+    dec = codec.NewDecoder(r, h)
+    dec = codec.NewDecoderBytes(b, h)
+    err = dec.Decode(&v)
+
+    enc = codec.NewEncoder(w, h)
+    enc = codec.NewEncoderBytes(&b, h)
+    err = enc.Encode(v)
+
+    //RPC Server
+    go func() {
+        for {
+            conn, err := listener.Accept()
+            rpcCodec := codec.GoRpc.ServerCodec(conn, h)
+            //OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
+            rpc.ServeCodec(rpcCodec)
+        }
+    }()
+
+    //RPC Communication (client side)
+    conn, err = net.Dial("tcp", "localhost:5555")
+    rpcCodec := codec.GoRpc.ClientCodec(conn, h)
+    //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
+    client := rpc.NewClientWithCodec(rpcCodec)
+
diff --git a/vendor/github.com/ugorji/go/codec/binc.go b/vendor/github.com/ugorji/go/codec/binc.go
index a3c96fe74..681b2b0da 100644
--- a/vendor/github.com/ugorji/go/codec/binc.go
+++ b/vendor/github.com/ugorji/go/codec/binc.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
@@ -55,77 +55,39 @@ const (
 	// others not currently supported
 )
 
-func bincdesc(vd, vs byte) string {
-	switch vd {
-	case bincVdSpecial:
-		switch vs {
-		case bincSpNil:
-			return "nil"
-		case bincSpFalse:
-			return "false"
-		case bincSpTrue:
-			return "true"
-		case bincSpNan, bincSpPosInf, bincSpNegInf, bincSpZeroFloat:
-			return "float"
-		case bincSpZero:
-			return "uint"
-		case bincSpNegOne:
-			return "int"
-		default:
-			return "unknown"
-		}
-	case bincVdSmallInt, bincVdPosInt:
-		return "uint"
-	case bincVdNegInt:
-		return "int"
-	case bincVdFloat:
-		return "float"
-	case bincVdSymbol:
-		return "string"
-	case bincVdString:
-		return "string"
-	case bincVdByteArray:
-		return "bytes"
-	case bincVdTimestamp:
-		return "time"
-	case bincVdCustomExt:
-		return "ext"
-	case bincVdArray:
-		return "array"
-	case bincVdMap:
-		return "map"
-	default:
-		return "unknown"
-	}
-}
-
 type bincEncDriver struct {
 	e *Encoder
-	h *BincHandle
 	w encWriter
 	m map[string]uint16 // symbols
-	b [16]byte          // scratch, used for encoding numbers - bigendian style
-	s uint16            // symbols sequencer
-	// c containerState
-	encDriverTrackContainerWriter
-	noBuiltInTypes
-	// encNoSeparator
+	b [scratchByteArrayLen]byte
+	s uint16 // symbols sequencer
+	encNoSeparator
 }
 
-func (e *bincEncDriver) EncodeNil() {
-	e.w.writen1(bincVdSpecial<<4 | bincSpNil)
+func (e *bincEncDriver) IsBuiltinType(rt uintptr) bool {
+	return rt == timeTypId
 }
 
-func (e *bincEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-	} else {
-		bs := bincEncodeTime(t)
+func (e *bincEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {
+	if rt == timeTypId {
+		var bs []byte
+		switch x := v.(type) {
+		case time.Time:
+			bs = encodeTime(x)
+		case *time.Time:
+			bs = encodeTime(*x)
+		default:
+			e.e.errorf("binc error encoding builtin: expect time.Time, received %T", v)
+		}
 		e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
 		e.w.writeb(bs)
 	}
 }
 
+func (e *bincEncDriver) EncodeNil() {
+	e.w.writen1(bincVdSpecial<<4 | bincSpNil)
+}
+
 func (e *bincEncDriver) EncodeBool(b bool) {
 	if b {
 		e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
@@ -233,21 +195,15 @@ func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
 	e.w.writen1(xtag)
 }
 
-func (e *bincEncDriver) WriteArrayStart(length int) {
+func (e *bincEncDriver) EncodeArrayStart(length int) {
 	e.encLen(bincVdArray<<4, uint64(length))
-	e.c = containerArrayStart
 }
 
-func (e *bincEncDriver) WriteMapStart(length int) {
+func (e *bincEncDriver) EncodeMapStart(length int) {
 	e.encLen(bincVdMap<<4, uint64(length))
-	e.c = containerMapStart
 }
 
 func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
-	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
-		e.EncodeSymbol(v)
-		return
-	}
 	l := uint64(len(v))
 	e.encBytesLen(c, l)
 	if l > 0 {
@@ -257,7 +213,7 @@ func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
 
 func (e *bincEncDriver) EncodeSymbol(v string) {
 	// if WriteSymbolsNoRefs {
-	// 	e.encodeString(cUTF8, v)
+	// 	e.encodeString(c_UTF8, v)
 	// 	return
 	// }
 
@@ -267,10 +223,10 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
 
 	l := len(v)
 	if l == 0 {
-		e.encBytesLen(cUTF8, 0)
+		e.encBytesLen(c_UTF8, 0)
 		return
 	} else if l == 1 {
-		e.encBytesLen(cUTF8, 1)
+		e.encBytesLen(c_UTF8, 1)
 		e.w.writen1(v[0])
 		return
 	}
@@ -320,10 +276,6 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
 }
 
 func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	if v == nil {
-		e.EncodeNil()
-		return
-	}
 	l := uint64(len(v))
 	e.encBytesLen(c, l)
 	if l > 0 {
@@ -333,7 +285,7 @@ func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 
 func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
 	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
-	if c == cRAW {
+	if c == c_RAW {
 		e.encLen(bincVdByteArray<<4, length)
 	} else {
 		e.encLen(bincVdString<<4, length)
@@ -372,9 +324,6 @@ type bincDecSymbol struct {
 }
 
 type bincDecDriver struct {
-	decDriverNoopContainerReader
-	noBuiltInTypes
-
 	d      *Decoder
 	h      *BincHandle
 	r      decReader
@@ -383,15 +332,13 @@ type bincDecDriver struct {
 	bd     byte
 	vd     byte
 	vs     byte
-	_      [3]byte // padding
+	noStreamingCodec
+	decNoSeparator
+	b [scratchByteArrayLen]byte
+
 	// linear searching on this slice is ok,
 	// because we typically expect < 32 symbols in each stream.
 	s []bincDecSymbol
-
-	// noStreamingCodec
-	// decNoSeparator
-
-	b [8 * 8]byte // scratch
 }
 
 func (d *bincDecDriver) readNextBd() {
@@ -409,9 +356,6 @@ func (d *bincDecDriver) uncacheRead() {
 }
 
 func (d *bincDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	if d.vd == bincVdSpecial && d.vs == bincSpNil {
 		return valueTypeNil
 	} else if d.vd == bincVdByteArray {
@@ -422,10 +366,9 @@ func (d *bincDecDriver) ContainerType() (vt valueType) {
 		return valueTypeArray
 	} else if d.vd == bincVdMap {
 		return valueTypeMap
+	} else {
+		// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
 	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
 	return valueTypeUnset
 }
 
@@ -440,24 +383,27 @@ func (d *bincDecDriver) TryDecodeAsNil() bool {
 	return false
 }
 
-func (d *bincDecDriver) DecodeTime() (t time.Time) {
+func (d *bincDecDriver) IsBuiltinType(rt uintptr) bool {
+	return rt == timeTypId
+}
+
+func (d *bincDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
+	if rt == timeTypId {
+		if d.vd != bincVdTimestamp {
+			d.d.errorf("Invalid d.vd. Expecting 0x%x. Received: 0x%x", bincVdTimestamp, d.vd)
+			return
+		}
+		tt, err := decodeTime(d.r.readx(int(d.vs)))
+		if err != nil {
+			panic(err)
+		}
+		var vt *time.Time = v.(*time.Time)
+		*vt = tt
 		d.bdRead = false
-		return
-	}
-	if d.vd != bincVdTimestamp {
-		d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	t, err := bincDecodeTime(d.r.readx(int(d.vs)))
-	if err != nil {
-		panic(err)
 	}
-	d.bdRead = false
-	return
 }
 
 func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
@@ -466,7 +412,7 @@ func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
 	} else {
 		l := d.r.readn1()
 		if l > 8 {
-			d.d.errorf("cannot read float - at most 8 bytes used to represent float - received %v bytes", l)
+			d.d.errorf("At most 8 bytes used to represent float. Received: %v bytes", l)
 			return
 		}
 		for i := l; i < 8; i++ {
@@ -485,7 +431,7 @@ func (d *bincDecDriver) decFloat() (f float64) {
 		d.decFloatPre(d.vs, 8)
 		f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
 	} else {
-		d.d.errorf("read float - only float32 and float64 are supported - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("only float32 and float64 are supported. d.vd: 0x%x, d.vs: 0x%x", d.vd, d.vs)
 		return
 	}
 	return
@@ -542,38 +488,49 @@ func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
 			neg = true
 			ui = 1
 		} else {
-			d.d.errorf("integer decode fails - invalid special value from descriptor %x-%x/%s",
-				d.vd, d.vs, bincdesc(d.vd, d.vs))
+			d.d.errorf("numeric decode fails for special value: d.vs: 0x%x", d.vs)
 			return
 		}
 	} else {
-		d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
+		d.d.errorf("number can only be decoded from uint or int values. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
 		return
 	}
 	return
 }
 
-func (d *bincDecDriver) DecodeInt64() (i int64) {
+func (d *bincDecDriver) DecodeInt(bitsize uint8) (i int64) {
 	ui, neg := d.decCheckInteger()
-	i = chkOvf.SignedIntV(ui)
+	i, overflow := chkOvf.SignedInt(ui)
+	if overflow {
+		d.d.errorf("simple: overflow converting %v to signed integer", ui)
+		return
+	}
 	if neg {
 		i = -i
 	}
+	if chkOvf.Int(i, bitsize) {
+		d.d.errorf("binc: overflow integer: %v", i)
+		return
+	}
 	d.bdRead = false
 	return
 }
 
-func (d *bincDecDriver) DecodeUint64() (ui uint64) {
+func (d *bincDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
 	ui, neg := d.decCheckInteger()
 	if neg {
-		d.d.errorf("assigning negative signed value to unsigned integer type")
+		d.d.errorf("Assigning negative signed value to unsigned type")
+		return
+	}
+	if chkOvf.Uint(ui, bitsize) {
+		d.d.errorf("binc: overflow integer: %v", ui)
 		return
 	}
 	d.bdRead = false
 	return
 }
 
-func (d *bincDecDriver) DecodeFloat64() (f float64) {
+func (d *bincDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -589,14 +546,17 @@ func (d *bincDecDriver) DecodeFloat64() (f float64) {
 		} else if vs == bincSpNegInf {
 			return math.Inf(-1)
 		} else {
-			d.d.errorf("float - invalid special value from descriptor %x-%x/%s",
-				d.vd, d.vs, bincdesc(d.vd, d.vs))
+			d.d.errorf("Invalid d.vs decoding float where d.vd=bincVdSpecial: %v", d.vs)
 			return
 		}
 	} else if vd == bincVdFloat {
 		f = d.decFloat()
 	} else {
-		f = float64(d.DecodeInt64())
+		f = float64(d.DecodeInt(64))
+	}
+	if chkOverflow32 && chkOvf.Float32(f) {
+		d.d.errorf("binc: float32 overflow: %v", f)
+		return
 	}
 	d.bdRead = false
 	return
@@ -612,7 +572,7 @@ func (d *bincDecDriver) DecodeBool() (b bool) {
 	} else if bd == (bincVdSpecial | bincSpTrue) {
 		b = true
 	} else {
-		d.d.errorf("bool - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd)
 		return
 	}
 	d.bdRead = false
@@ -620,11 +580,8 @@ func (d *bincDecDriver) DecodeBool() (b bool) {
 }
 
 func (d *bincDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	if d.vd != bincVdMap {
-		d.d.errorf("map - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("Invalid d.vd for map. Expecting 0x%x. Got: 0x%x", bincVdMap, d.vd)
 		return
 	}
 	length = d.decLen()
@@ -633,11 +590,8 @@ func (d *bincDecDriver) ReadMapStart() (length int) {
 }
 
 func (d *bincDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	if d.vd != bincVdArray {
-		d.d.errorf("array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("Invalid d.vd for array. Expecting 0x%x. Got: 0x%x", bincVdArray, d.vd)
 		return
 	}
 	length = d.decLen()
@@ -668,8 +622,7 @@ func (d *bincDecDriver) decLenNumber() (v uint64) {
 	return
 }
 
-func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (
-	bs2 []byte, s string) {
+func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (bs2 []byte, s string) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -677,7 +630,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
 		d.bdRead = false
 		return
 	}
-	var slen = -1
+	var slen int = -1
 	// var ok bool
 	switch d.vd {
 	case bincVdString, bincVdByteArray:
@@ -750,7 +703,8 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
 			d.s = append(d.s, bincDecSymbol{i: symbol, s: s, b: bs2})
 		}
 	default:
-		d.d.errorf("string/bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("Invalid d.vd. Expecting string:0x%x, bytearray:0x%x or symbol: 0x%x. Got: 0x%x",
+			bincVdString, bincVdByteArray, bincVdSymbol, d.vd)
 		return
 	}
 	d.bdRead = false
@@ -765,12 +719,11 @@ func (d *bincDecDriver) DecodeString() (s string) {
 	return
 }
 
-func (d *bincDecDriver) DecodeStringAsBytes() (s []byte) {
-	s, _ = d.decStringAndBytes(d.b[:], false, true)
-	return
-}
-
-func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+func (d *bincDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) {
+	if isstring {
+		bsOut, _ = d.decStringAndBytes(bs, false, zerocopy)
+		return
+	}
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -778,16 +731,12 @@ func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 		d.bdRead = false
 		return nil
 	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.vd == bincVdArray {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
 	var clen int
 	if d.vd == bincVdString || d.vd == bincVdByteArray {
 		clen = d.decLen()
 	} else {
-		d.d.errorf("bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("Invalid d.vd for bytes. Expecting string:0x%x or bytearray:0x%x. Got: 0x%x",
+			bincVdString, bincVdByteArray, d.vd)
 		return
 	}
 	d.bdRead = false
@@ -803,7 +752,7 @@ func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 
 func (d *bincDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
 	if xtag > 0xff {
-		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
+		d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
 		return
 	}
 	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
@@ -826,14 +775,14 @@ func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []b
 		l := d.decLen()
 		xtag = d.r.readn1()
 		if verifyTag && xtag != tag {
-			d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
+			d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", xtag, tag)
 			return
 		}
 		xbs = d.r.readx(l)
 	} else if d.vd == bincVdByteArray {
-		xbs = d.DecodeBytes(nil, true)
+		xbs = d.DecodeBytes(nil, false, true)
 	} else {
-		d.d.errorf("ext - expecting extensions or byte array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("Invalid d.vd for extensions (Expecting extensions or byte array). Got: 0x%x", d.vd)
 		return
 	}
 	d.bdRead = false
@@ -845,7 +794,7 @@ func (d *bincDecDriver) DecodeNaked() {
 		d.readNextBd()
 	}
 
-	n := d.d.n
+	n := &d.d.n
 	var decodeFurther bool
 
 	switch d.vd {
@@ -878,7 +827,7 @@ func (d *bincDecDriver) DecodeNaked() {
 			n.v = valueTypeInt
 			n.i = int64(-1) // int8(-1)
 		default:
-			d.d.errorf("cannot infer value - unrecognized special value from descriptor %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
+			d.d.errorf("decodeNaked: Unrecognized special value 0x%x", d.vs)
 		}
 	case bincVdSmallInt:
 		n.v = valueTypeUint
@@ -900,10 +849,10 @@ func (d *bincDecDriver) DecodeNaked() {
 		n.s = d.DecodeString()
 	case bincVdByteArray:
 		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
+		n.l = d.DecodeBytes(nil, false, false)
 	case bincVdTimestamp:
-		n.v = valueTypeTime
-		tt, err := bincDecodeTime(d.r.readx(int(d.vs)))
+		n.v = valueTypeTimestamp
+		tt, err := decodeTime(d.r.readx(int(d.vs)))
 		if err != nil {
 			panic(err)
 		}
@@ -920,7 +869,7 @@ func (d *bincDecDriver) DecodeNaked() {
 		n.v = valueTypeMap
 		decodeFurther = true
 	default:
-		d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("decodeNaked: Unrecognized d.vd: 0x%x", d.vd)
 	}
 
 	if !decodeFurther {
@@ -950,219 +899,31 @@ func (d *bincDecDriver) DecodeNaked() {
 type BincHandle struct {
 	BasicHandle
 	binaryEncodingType
-	noElemSeparators
-
-	// AsSymbols defines what should be encoded as symbols.
-	//
-	// Encoding as symbols can reduce the encoded size significantly.
-	//
-	// However, during decoding, each string to be encoded as a symbol must
-	// be checked to see if it has been seen before. Consequently, encoding time
-	// will increase if using symbols, because string comparisons has a clear cost.
-	//
-	// Values:
-	// - 0: default: library uses best judgement
-	// - 1: use symbols
-	// - 2: do not use symbols
-	AsSymbols uint8
-
-	// AsSymbols: may later on introduce more options ...
-	// - m: map keys
-	// - s: struct fields
-	// - n: none
-	// - a: all: same as m, s, ...
-
-	// _ [1]uint64 // padding
 }
 
-// Name returns the name of the handle: binc
-func (h *BincHandle) Name() string { return "binc" }
-
-// SetBytesExt sets an extension
 func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
+	return h.SetExt(rt, tag, &setExtWrapper{b: ext})
 }
 
 func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
-	return &bincEncDriver{e: e, h: h, w: e.w}
+	return &bincEncDriver{e: e, w: e.w}
 }
 
 func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
-	return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+	return &bincDecDriver{d: d, r: d.r, h: h, br: d.bytes}
 }
 
 func (e *bincEncDriver) reset() {
 	e.w = e.e.w
 	e.s = 0
-	e.c = 0
 	e.m = nil
 }
 
 func (d *bincDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
+	d.r = d.d.r
 	d.s = nil
 	d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
 }
 
-// var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
-
-// EncodeTime encodes a time.Time as a []byte, including
-// information on the instant in time and UTC offset.
-//
-// Format Description
-//
-//   A timestamp is composed of 3 components:
-//
-//   - secs: signed integer representing seconds since unix epoch
-//   - nsces: unsigned integer representing fractional seconds as a
-//     nanosecond offset within secs, in the range 0 <= nsecs < 1e9
-//   - tz: signed integer representing timezone offset in minutes east of UTC,
-//     and a dst (daylight savings time) flag
-//
-//   When encoding a timestamp, the first byte is the descriptor, which
-//   defines which components are encoded and how many bytes are used to
-//   encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
-//   is not encoded in the byte array explicitly*.
-//
-//       Descriptor 8 bits are of the form `A B C DDD EE`:
-//           A:   Is secs component encoded? 1 = true
-//           B:   Is nsecs component encoded? 1 = true
-//           C:   Is tz component encoded? 1 = true
-//           DDD: Number of extra bytes for secs (range 0-7).
-//                If A = 1, secs encoded in DDD+1 bytes.
-//                    If A = 0, secs is not encoded, and is assumed to be 0.
-//                    If A = 1, then we need at least 1 byte to encode secs.
-//                    DDD says the number of extra bytes beyond that 1.
-//                    E.g. if DDD=0, then secs is represented in 1 byte.
-//                         if DDD=2, then secs is represented in 3 bytes.
-//           EE:  Number of extra bytes for nsecs (range 0-3).
-//                If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
-//
-//   Following the descriptor bytes, subsequent bytes are:
-//
-//       secs component encoded in `DDD + 1` bytes (if A == 1)
-//       nsecs component encoded in `EE + 1` bytes (if B == 1)
-//       tz component encoded in 2 bytes (if C == 1)
-//
-//   secs and nsecs components are integers encoded in a BigEndian
-//   2-complement encoding format.
-//
-//   tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
-//   Least significant bit 0 are described below:
-//
-//       Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
-//       Bit 15 = have\_dst: set to 1 if we set the dst flag.
-//       Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
-//       Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
-//
-func bincEncodeTime(t time.Time) []byte {
-	//t := rv.Interface().(time.Time)
-	tsecs, tnsecs := t.Unix(), t.Nanosecond()
-	var (
-		bd   byte
-		btmp [8]byte
-		bs   [16]byte
-		i    int = 1
-	)
-	l := t.Location()
-	if l == time.UTC {
-		l = nil
-	}
-	if tsecs != 0 {
-		bd = bd | 0x80
-		bigen.PutUint64(btmp[:], uint64(tsecs))
-		f := pruneSignExt(btmp[:], tsecs >= 0)
-		bd = bd | (byte(7-f) << 2)
-		copy(bs[i:], btmp[f:])
-		i = i + (8 - f)
-	}
-	if tnsecs != 0 {
-		bd = bd | 0x40
-		bigen.PutUint32(btmp[:4], uint32(tnsecs))
-		f := pruneSignExt(btmp[:4], true)
-		bd = bd | byte(3-f)
-		copy(bs[i:], btmp[f:4])
-		i = i + (4 - f)
-	}
-	if l != nil {
-		bd = bd | 0x20
-		// Note that Go Libs do not give access to dst flag.
-		_, zoneOffset := t.Zone()
-		//zoneName, zoneOffset := t.Zone()
-		zoneOffset /= 60
-		z := uint16(zoneOffset)
-		bigen.PutUint16(btmp[:2], z)
-		// clear dst flags
-		bs[i] = btmp[0] & 0x3f
-		bs[i+1] = btmp[1]
-		i = i + 2
-	}
-	bs[0] = bd
-	return bs[0:i]
-}
-
-// bincDecodeTime decodes a []byte into a time.Time.
-func bincDecodeTime(bs []byte) (tt time.Time, err error) {
-	bd := bs[0]
-	var (
-		tsec  int64
-		tnsec uint32
-		tz    uint16
-		i     byte = 1
-		i2    byte
-		n     byte
-	)
-	if bd&(1<<7) != 0 {
-		var btmp [8]byte
-		n = ((bd >> 2) & 0x7) + 1
-		i2 = i + n
-		copy(btmp[8-n:], bs[i:i2])
-		//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
-		if bs[i]&(1<<7) != 0 {
-			copy(btmp[0:8-n], bsAll0xff)
-			//for j,k := byte(0), 8-n; j < k; j++ {	btmp[j] = 0xff }
-		}
-		i = i2
-		tsec = int64(bigen.Uint64(btmp[:]))
-	}
-	if bd&(1<<6) != 0 {
-		var btmp [4]byte
-		n = (bd & 0x3) + 1
-		i2 = i + n
-		copy(btmp[4-n:], bs[i:i2])
-		i = i2
-		tnsec = bigen.Uint32(btmp[:])
-	}
-	if bd&(1<<5) == 0 {
-		tt = time.Unix(tsec, int64(tnsec)).UTC()
-		return
-	}
-	// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
-	// However, we need name here, so it can be shown when time is printed.
-	// Zone name is in form: UTC-08:00.
-	// Note that Go Libs do not give access to dst flag, so we ignore dst bits
-
-	i2 = i + 2
-	tz = bigen.Uint16(bs[i:i2])
-	// i = i2
-	// sign extend sign bit into top 2 MSB (which were dst bits):
-	if tz&(1<<13) == 0 { // positive
-		tz = tz & 0x3fff //clear 2 MSBs: dst bits
-	} else { // negative
-		tz = tz | 0xc000 //set 2 MSBs: dst bits
-	}
-	tzint := int16(tz)
-	if tzint == 0 {
-		tt = time.Unix(tsec, int64(tnsec)).UTC()
-	} else {
-		// For Go Time, do not use a descriptive timezone.
-		// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
-		// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
-		// var zoneName = timeLocUTCName(tzint)
-		tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
-	}
-	return
-}
-
 var _ decDriver = (*bincDecDriver)(nil)
 var _ encDriver = (*bincEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/cbor.go b/vendor/github.com/ugorji/go/codec/cbor.go
index 7633c04ac..c87e3f4d4 100644
--- a/vendor/github.com/ugorji/go/codec/cbor.go
+++ b/vendor/github.com/ugorji/go/codec/cbor.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
@@ -6,7 +6,6 @@ package codec
 import (
 	"math"
 	"reflect"
-	"time"
 )
 
 const (
@@ -39,8 +38,6 @@ const (
 	cborBdBreak                 = 0xff
 )
 
-// These define some in-stream descriptors for
-// manual encoding e.g. when doing explicit indefinite-length
 const (
 	CborStreamBytes  byte = 0x5f
 	CborStreamString      = 0x7f
@@ -60,57 +57,15 @@ const (
 	cborBaseSimple      = 0xe0
 )
 
-func cbordesc(bd byte) string {
-	switch bd {
-	case cborBdNil:
-		return "nil"
-	case cborBdFalse:
-		return "false"
-	case cborBdTrue:
-		return "true"
-	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
-		return "float"
-	case cborBdIndefiniteBytes:
-		return "bytes*"
-	case cborBdIndefiniteString:
-		return "string*"
-	case cborBdIndefiniteArray:
-		return "array*"
-	case cborBdIndefiniteMap:
-		return "map*"
-	default:
-		switch {
-		case bd >= cborBaseUint && bd < cborBaseNegInt:
-			return "(u)int"
-		case bd >= cborBaseNegInt && bd < cborBaseBytes:
-			return "int"
-		case bd >= cborBaseBytes && bd < cborBaseString:
-			return "bytes"
-		case bd >= cborBaseString && bd < cborBaseArray:
-			return "string"
-		case bd >= cborBaseArray && bd < cborBaseMap:
-			return "array"
-		case bd >= cborBaseMap && bd < cborBaseTag:
-			return "map"
-		case bd >= cborBaseTag && bd < cborBaseSimple:
-			return "ext"
-		default:
-			return "unknown"
-		}
-	}
-}
-
 // -------------------
 
 type cborEncDriver struct {
 	noBuiltInTypes
-	encDriverNoopContainerWriter
-	// encNoSeparator
+	encNoSeparator
 	e *Encoder
 	w encWriter
 	h *CborHandle
 	x [8]byte
-	_ [3]uint64 // padding
 }
 
 func (e *cborEncDriver) EncodeNil() {
@@ -168,24 +123,6 @@ func (e *cborEncDriver) encLen(bd byte, length int) {
 	e.encUint(uint64(length), bd)
 }
 
-func (e *cborEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-	} else if e.h.TimeRFC3339 {
-		e.encUint(0, cborBaseTag)
-		e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
-	} else {
-		e.encUint(1, cborBaseTag)
-		t = t.UTC().Round(time.Microsecond)
-		sec, nsec := t.Unix(), uint64(t.Nanosecond())
-		if nsec == 0 {
-			e.EncodeInt(sec)
-		} else {
-			e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
-		}
-	}
-}
-
 func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
 	e.encUint(uint64(xtag), cborBaseTag)
 	if v := ext.ConvertExt(rv); v == nil {
@@ -197,103 +134,53 @@ func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Enco
 
 func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
 	e.encUint(uint64(re.Tag), cborBaseTag)
-	if false && re.Data != nil {
+	if re.Data != nil {
 		en.encode(re.Data)
-	} else if re.Value != nil {
-		en.encode(re.Value)
-	} else {
+	} else if re.Value == nil {
 		e.EncodeNil()
-	}
-}
-
-func (e *cborEncDriver) WriteArrayStart(length int) {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdIndefiniteArray)
 	} else {
-		e.encLen(cborBaseArray, length)
-	}
-}
-
-func (e *cborEncDriver) WriteMapStart(length int) {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdIndefiniteMap)
-	} else {
-		e.encLen(cborBaseMap, length)
+		en.encode(re.Value)
 	}
 }
 
-func (e *cborEncDriver) WriteMapEnd() {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdBreak)
-	}
+func (e *cborEncDriver) EncodeArrayStart(length int) {
+	e.encLen(cborBaseArray, length)
 }
 
-func (e *cborEncDriver) WriteArrayEnd() {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdBreak)
-	}
+func (e *cborEncDriver) EncodeMapStart(length int) {
+	e.encLen(cborBaseMap, length)
 }
 
 func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
-	e.encStringBytesS(cborBaseString, v)
+	e.encLen(cborBaseString, len(v))
+	e.w.writestr(v)
 }
 
-func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	if v == nil {
-		e.EncodeNil()
-	} else if c == cRAW {
-		e.encStringBytesS(cborBaseBytes, stringView(v))
-	} else {
-		e.encStringBytesS(cborBaseString, stringView(v))
-	}
+func (e *cborEncDriver) EncodeSymbol(v string) {
+	e.EncodeString(c_UTF8, v)
 }
 
-func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
-	if e.h.IndefiniteLength {
-		if bb == cborBaseBytes {
-			e.w.writen1(cborBdIndefiniteBytes)
-		} else {
-			e.w.writen1(cborBdIndefiniteString)
-		}
-		blen := len(v) / 4
-		if blen == 0 {
-			blen = 64
-		} else if blen > 1024 {
-			blen = 1024
-		}
-		for i := 0; i < len(v); {
-			var v2 string
-			i2 := i + blen
-			if i2 < len(v) {
-				v2 = v[i:i2]
-			} else {
-				v2 = v[i:]
-			}
-			e.encLen(bb, len(v2))
-			e.w.writestr(v2)
-			i = i2
-		}
-		e.w.writen1(cborBdBreak)
+func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
+	if c == c_RAW {
+		e.encLen(cborBaseBytes, len(v))
 	} else {
-		e.encLen(bb, len(v))
-		e.w.writestr(v)
+		e.encLen(cborBaseString, len(v))
 	}
+	e.w.writeb(v)
 }
 
 // ----------------------
 
 type cborDecDriver struct {
-	d *Decoder
-	h *CborHandle
-	r decReader
-	// b      [scratchByteArrayLen]byte
+	d      *Decoder
+	h      *CborHandle
+	r      decReader
+	b      [scratchByteArrayLen]byte
 	br     bool // bytes reader
 	bdRead bool
 	bd     byte
 	noBuiltInTypes
-	// decNoSeparator
-	decDriverNoopContainerReader
-	_ [3]uint64 // padding
+	decNoSeparator
 }
 
 func (d *cborDecDriver) readNextBd() {
@@ -309,9 +196,6 @@ func (d *cborDecDriver) uncacheRead() {
 }
 
 func (d *cborDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	if d.bd == cborBdNil {
 		return valueTypeNil
 	} else if d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) {
@@ -322,10 +206,9 @@ func (d *cborDecDriver) ContainerType() (vt valueType) {
 		return valueTypeArray
 	} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
 		return valueTypeMap
+	} else {
+		// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
 	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
 	return valueTypeUnset
 }
 
@@ -366,7 +249,7 @@ func (d *cborDecDriver) decUint() (ui uint64) {
 		} else if v == 0x1b {
 			ui = uint64(bigen.Uint64(d.r.readx(8)))
 		} else {
-			d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
+			d.d.errorf("decUint: Invalid descriptor: %v", d.bd)
 			return
 		}
 	}
@@ -382,36 +265,52 @@ func (d *cborDecDriver) decCheckInteger() (neg bool) {
 	} else if major == cborMajorNegInt {
 		neg = true
 	} else {
-		d.d.errorf("not an integer - invalid major %v from descriptor %x/%s", major, d.bd, cbordesc(d.bd))
+		d.d.errorf("invalid major: %v (bd: %v)", major, d.bd)
 		return
 	}
 	return
 }
 
-func (d *cborDecDriver) DecodeInt64() (i int64) {
+func (d *cborDecDriver) DecodeInt(bitsize uint8) (i int64) {
 	neg := d.decCheckInteger()
 	ui := d.decUint()
 	// check if this number can be converted to an int without overflow
+	var overflow bool
 	if neg {
-		i = -(chkOvf.SignedIntV(ui + 1))
+		if i, overflow = chkOvf.SignedInt(ui + 1); overflow {
+			d.d.errorf("cbor: overflow converting %v to signed integer", ui+1)
+			return
+		}
+		i = -i
 	} else {
-		i = chkOvf.SignedIntV(ui)
+		if i, overflow = chkOvf.SignedInt(ui); overflow {
+			d.d.errorf("cbor: overflow converting %v to signed integer", ui)
+			return
+		}
+	}
+	if chkOvf.Int(i, bitsize) {
+		d.d.errorf("cbor: overflow integer: %v", i)
+		return
 	}
 	d.bdRead = false
 	return
 }
 
-func (d *cborDecDriver) DecodeUint64() (ui uint64) {
+func (d *cborDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
 	if d.decCheckInteger() {
-		d.d.errorf("assigning negative signed value to unsigned type")
+		d.d.errorf("Assigning negative signed value to unsigned type")
 		return
 	}
 	ui = d.decUint()
+	if chkOvf.Uint(ui, bitsize) {
+		d.d.errorf("cbor: overflow integer: %v", ui)
+		return
+	}
 	d.bdRead = false
 	return
 }
 
-func (d *cborDecDriver) DecodeFloat64() (f float64) {
+func (d *cborDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -422,9 +321,13 @@ func (d *cborDecDriver) DecodeFloat64() (f float64) {
 	} else if bd == cborBdFloat64 {
 		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
 	} else if bd >= cborBaseUint && bd < cborBaseBytes {
-		f = float64(d.DecodeInt64())
+		f = float64(d.DecodeInt(64))
 	} else {
-		d.d.errorf("float only valid from float16/32/64 - invalid descriptor %x/%s", bd, cbordesc(bd))
+		d.d.errorf("Float only valid from float16/32/64: Invalid descriptor: %v", bd)
+		return
+	}
+	if chkOverflow32 && chkOvf.Float32(f) {
+		d.d.errorf("cbor: float32 overflow: %v", f)
 		return
 	}
 	d.bdRead = false
@@ -440,7 +343,7 @@ func (d *cborDecDriver) DecodeBool() (b bool) {
 		b = true
 	} else if bd == cborBdFalse {
 	} else {
-		d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
+		d.d.errorf("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd)
 		return
 	}
 	d.bdRead = false
@@ -448,9 +351,6 @@ func (d *cborDecDriver) DecodeBool() (b bool) {
 }
 
 func (d *cborDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	d.bdRead = false
 	if d.bd == cborBdIndefiniteMap {
 		return -1
@@ -459,9 +359,6 @@ func (d *cborDecDriver) ReadMapStart() (length int) {
 }
 
 func (d *cborDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	d.bdRead = false
 	if d.bd == cborBdIndefiniteArray {
 		return -1
@@ -480,8 +377,7 @@ func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
 			break
 		}
 		if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
-			d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
-				" got major %v from descriptor %x/%x", major, d.bd, cbordesc(d.bd))
+			d.d.errorf("cbor: expect bytes or string major type in indefinite string/bytes; got: %v, byte: %v", major, d.bd)
 			return nil
 		}
 		n := d.decLen()
@@ -502,7 +398,7 @@ func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
 	return bs
 }
 
-func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+func (d *cborDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -511,84 +407,25 @@ func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 		return nil
 	}
 	if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
-		d.bdRead = false
 		if bs == nil {
-			if zerocopy {
-				return d.decAppendIndefiniteBytes(d.d.b[:0])
-			}
-			return d.decAppendIndefiniteBytes(zeroByteSlice)
+			return d.decAppendIndefiniteBytes(nil)
 		}
 		return d.decAppendIndefiniteBytes(bs[:0])
 	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
 	clen := d.decLen()
 	d.bdRead = false
 	if zerocopy {
 		if d.br {
 			return d.r.readx(clen)
 		} else if len(bs) == 0 {
-			bs = d.d.b[:]
+			bs = d.b[:]
 		}
 	}
-	return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
+	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
 }
 
 func (d *cborDecDriver) DecodeString() (s string) {
-	return string(d.DecodeBytes(d.d.b[:], true))
-}
-
-func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
-	return d.DecodeBytes(d.d.b[:], true)
-}
-
-func (d *cborDecDriver) DecodeTime() (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdNil || d.bd == cborBdUndefined {
-		d.bdRead = false
-		return
-	}
-	xtag := d.decUint()
-	d.bdRead = false
-	return d.decodeTime(xtag)
-}
-
-func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch xtag {
-	case 0:
-		var err error
-		if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
-			d.d.errorv(err)
-		}
-	case 1:
-		// decode an int64 or a float, and infer time.Time from there.
-		// for floats, round to microseconds, as that is what is guaranteed to fit well.
-		switch {
-		case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
-			f1, f2 := math.Modf(d.DecodeFloat64())
-			t = time.Unix(int64(f1), int64(f2*1e9))
-		case d.bd == cborBdFloat64:
-			f1, f2 := math.Modf(d.DecodeFloat64())
-			t = time.Unix(int64(f1), int64(f2*1e9))
-		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
-			d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
-			t = time.Unix(d.DecodeInt64(), 0)
-		default:
-			d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
-		}
-	default:
-		d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
-	}
-	t = t.UTC().Round(time.Microsecond)
-	return
+	return string(d.DecodeBytes(d.b[:], true, true))
 }
 
 func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
@@ -619,7 +456,7 @@ func (d *cborDecDriver) DecodeNaked() {
 		d.readNextBd()
 	}
 
-	n := d.d.n
+	n := &d.d.n
 	var decodeFurther bool
 
 	switch d.bd {
@@ -631,12 +468,15 @@ func (d *cborDecDriver) DecodeNaked() {
 	case cborBdTrue:
 		n.v = valueTypeBool
 		n.b = true
-	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
+	case cborBdFloat16, cborBdFloat32:
 		n.v = valueTypeFloat
-		n.f = d.DecodeFloat64()
+		n.f = d.DecodeFloat(true)
+	case cborBdFloat64:
+		n.v = valueTypeFloat
+		n.f = d.DecodeFloat(false)
 	case cborBdIndefiniteBytes:
 		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
+		n.l = d.DecodeBytes(nil, false, false)
 	case cborBdIndefiniteString:
 		n.v = valueTypeString
 		n.s = d.DecodeString()
@@ -651,17 +491,17 @@ func (d *cborDecDriver) DecodeNaked() {
 		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
 			if d.h.SignedInteger {
 				n.v = valueTypeInt
-				n.i = d.DecodeInt64()
+				n.i = d.DecodeInt(64)
 			} else {
 				n.v = valueTypeUint
-				n.u = d.DecodeUint64()
+				n.u = d.DecodeUint(64)
 			}
 		case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
 			n.v = valueTypeInt
-			n.i = d.DecodeInt64()
+			n.i = d.DecodeInt(64)
 		case d.bd >= cborBaseBytes && d.bd < cborBaseString:
 			n.v = valueTypeBytes
-			n.l = d.DecodeBytes(nil, false)
+			n.l = d.DecodeBytes(nil, false, false)
 		case d.bd >= cborBaseString && d.bd < cborBaseArray:
 			n.v = valueTypeString
 			n.s = d.DecodeString()
@@ -675,11 +515,6 @@ func (d *cborDecDriver) DecodeNaked() {
 			n.v = valueTypeExt
 			n.u = d.decUint()
 			n.l = nil
-			if n.u == 0 || n.u == 1 {
-				d.bdRead = false
-				n.v = valueTypeTime
-				n.t = d.decodeTime(n.u)
-			}
 			// d.bdRead = false
 			// d.d.decode(&re.Value) // handled by decode itself.
 			// decodeFurther = true
@@ -710,29 +545,30 @@ func (d *cborDecDriver) DecodeNaked() {
 //
 // None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
 // Users can implement them as needed (using SetExt), including spec-documented ones:
-//   - timestamp, BigNum, BigFloat, Decimals,
-//   - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
+//   - timestamp, BigNum, BigFloat, Decimals, Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
+//
+// To encode with indefinite lengths (streaming), users will use
+// (Must)Encode methods of *Encoder, along with writing CborStreamXXX constants.
+//
+// For example, to encode "one-byte" as an indefinite length string:
+//     var buf bytes.Buffer
+//     e := NewEncoder(&buf, new(CborHandle))
+//     buf.WriteByte(CborStreamString)
+//     e.MustEncode("one-")
+//     e.MustEncode("byte")
+//     buf.WriteByte(CborStreamBreak)
+//     encodedBytes := buf.Bytes()
+//     var vv interface{}
+//     NewDecoderBytes(buf.Bytes(), new(CborHandle)).MustDecode(&vv)
+//     // Now, vv contains the same string "one-byte"
+//
 type CborHandle struct {
 	binaryEncodingType
-	noElemSeparators
 	BasicHandle
-
-	// IndefiniteLength=true, means that we encode using indefinitelength
-	IndefiniteLength bool
-
-	// TimeRFC3339 says to encode time.Time using RFC3339 format.
-	// If unset, we encode time.Time using seconds past epoch.
-	TimeRFC3339 bool
-
-	// _ [1]uint64 // padding
 }
 
-// Name returns the name of the handle: cbor
-func (h *CborHandle) Name() string { return "cbor" }
-
-// SetInterfaceExt sets an extension
 func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
+	return h.SetExt(rt, tag, &setExtWrapper{i: ext})
 }
 
 func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
@@ -740,7 +576,7 @@ func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
 }
 
 func (h *CborHandle) newDecDriver(d *Decoder) decDriver {
-	return &cborDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+	return &cborDecDriver{d: d, r: d.r, h: h, br: d.bytes}
 }
 
 func (e *cborEncDriver) reset() {
@@ -748,7 +584,7 @@ func (e *cborEncDriver) reset() {
 }
 
 func (d *cborDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
+	d.r = d.d.r
 	d.bd, d.bdRead = 0, false
 }
 
diff --git a/vendor/github.com/ugorji/go/codec/decode.go b/vendor/github.com/ugorji/go/codec/decode.go
index 1c0817aaf..e30e8e8c1 100644
--- a/vendor/github.com/ugorji/go/codec/decode.go
+++ b/vendor/github.com/ugorji/go/codec/decode.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
@@ -9,33 +9,18 @@ import (
 	"fmt"
 	"io"
 	"reflect"
-	"strconv"
-	"sync"
 	"time"
 )
 
 // Some tagging information for error messages.
 const (
-	msgBadDesc            = "unrecognized descriptor byte"
+	msgBadDesc            = "Unrecognized descriptor byte"
 	msgDecCannotExpandArr = "cannot expand go array from %v to stream length: %v"
 )
 
-const decDefSliceCap = 8
-const decDefChanCap = 64 // should be large, as cap cannot be expanded
-const decScratchByteArrayLen = cacheLineSize - 8
-
 var (
-	errstrOnlyMapOrArrayCanDecodeIntoStruct = "only encoded map or array can be decoded into a struct"
-	errstrCannotDecodeIntoNil               = "cannot decode into nil"
-
-	errmsgExpandSliceOverflow     = "expand slice: slice overflow"
-	errmsgExpandSliceCannotChange = "expand slice: cannot change"
-
-	errDecoderNotInitialized = errors.New("Decoder not initialized")
-
-	errDecUnreadByteNothingToRead   = errors.New("cannot unread - nothing has been read")
-	errDecUnreadByteLastByteNotRead = errors.New("cannot unread - last byte has not been read")
-	errDecUnreadByteUnknown         = errors.New("cannot unread - reason unknown")
+	onlyMapOrArrayCanDecodeIntoStructErr = errors.New("only encoded map or array can be decoded into a struct")
+	cannotDecodeIntoNilErr               = errors.New("cannot decode into nil")
 )
 
 // decReader abstracts the reading source, allowing implementations that can
@@ -49,29 +34,25 @@ type decReader interface {
 	readx(n int) []byte
 	readb([]byte)
 	readn1() uint8
+	readn1eof() (v uint8, eof bool)
 	numread() int // number of bytes read
 	track()
 	stopTrack() []byte
+}
 
-	// skip will skip any byte that matches, and return the first non-matching byte
-	skip(accept *bitset256) (token byte)
-	// readTo will read any byte that matches, stopping once no-longer matching.
-	readTo(in []byte, accept *bitset256) (out []byte)
-	// readUntil will read, only stopping once it matches the 'stop' byte.
-	readUntil(in []byte, stop byte) (out []byte)
+type decReaderByteScanner interface {
+	io.Reader
+	io.ByteScanner
 }
 
 type decDriver interface {
 	// this will check if the next token is a break.
 	CheckBreak() bool
-	// Note: TryDecodeAsNil should be careful not to share any temporary []byte with
-	// the rest of the decDriver. This is because sometimes, we optimize by holding onto
-	// a transient []byte, and ensuring the only other call we make to the decDriver
-	// during that time is maybe a TryDecodeAsNil() call.
 	TryDecodeAsNil() bool
 	// vt is one of: Bytes, String, Nil, Slice or Map. Return unSet if not known.
 	ContainerType() (vt valueType)
-	// IsBuiltinType(rt uintptr) bool
+	IsBuiltinType(rt uintptr) bool
+	DecodeBuiltin(rt uintptr, v interface{})
 
 	// DecodeNaked will decode primitives (number, bool, string, []byte) and RawExt.
 	// For maps and arrays, it will not do the decoding in-band, but will signal
@@ -85,15 +66,9 @@ type decDriver interface {
 	// extensions should also use readx to decode them, for efficiency.
 	// kInterface will extract the detached byte slice if it has to pass it outside its realm.
 	DecodeNaked()
-
-	// Deprecated: use DecodeInt64 and DecodeUint64 instead
-	// DecodeInt(bitsize uint8) (i int64)
-	// DecodeUint(bitsize uint8) (ui uint64)
-
-	DecodeInt64() (i int64)
-	DecodeUint64() (ui uint64)
-
-	DecodeFloat64() (f float64)
+	DecodeInt(bitsize uint8) (i int64)
+	DecodeUint(bitsize uint8) (ui uint64)
+	DecodeFloat(chkOverflow32 bool) (f float64)
 	DecodeBool() (b bool)
 	// DecodeString can also decode symbols.
 	// It looks redundant as DecodeBytes is available.
@@ -101,69 +76,45 @@ type decDriver interface {
 	// return a pre-stored string value, meaning that it can bypass
 	// the cost of []byte->string conversion.
 	DecodeString() (s string)
-	DecodeStringAsBytes() (v []byte)
 
 	// DecodeBytes may be called directly, without going through reflection.
 	// Consequently, it must be designed to handle possible nil.
-	DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
-	// DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte)
+	DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte)
 
 	// decodeExt will decode into a *RawExt or into an extension.
 	DecodeExt(v interface{}, xtag uint64, ext Ext) (realxtag uint64)
 	// decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte)
-
-	DecodeTime() (t time.Time)
-
-	ReadArrayStart() int
-	ReadArrayElem()
-	ReadArrayEnd()
 	ReadMapStart() int
-	ReadMapElemKey()
-	ReadMapElemValue()
-	ReadMapEnd()
+	ReadArrayStart() int
 
 	reset()
 	uncacheRead()
 }
 
-type decDriverNoopContainerReader struct{}
+type decNoSeparator struct {
+}
 
-func (x decDriverNoopContainerReader) ReadArrayStart() (v int) { return }
-func (x decDriverNoopContainerReader) ReadArrayElem()          {}
-func (x decDriverNoopContainerReader) ReadArrayEnd()           {}
-func (x decDriverNoopContainerReader) ReadMapStart() (v int)   { return }
-func (x decDriverNoopContainerReader) ReadMapElemKey()         {}
-func (x decDriverNoopContainerReader) ReadMapElemValue()       {}
-func (x decDriverNoopContainerReader) ReadMapEnd()             {}
-func (x decDriverNoopContainerReader) CheckBreak() (v bool)    { return }
+func (_ decNoSeparator) ReadEnd() {}
 
-// func (x decNoSeparator) uncacheRead() {}
+// func (_ decNoSeparator) uncacheRead() {}
 
-// DecodeOptions captures configuration options during decode.
 type DecodeOptions struct {
 	// MapType specifies type to use during schema-less decoding of a map in the stream.
-	// If nil (unset), we default to map[string]interface{} iff json handle and MapStringAsKey=true,
-	// else map[interface{}]interface{}.
+	// If nil, we use map[interface{}]interface{}
 	MapType reflect.Type
 
 	// SliceType specifies type to use during schema-less decoding of an array in the stream.
-	// If nil (unset), we default to []interface{} for all formats.
+	// If nil, we use []interface{}
 	SliceType reflect.Type
 
-	// MaxInitLen defines the maxinum initial length that we "make" a collection
-	// (string, slice, map, chan). If 0 or negative, we default to a sensible value
-	// based on the size of an element in the collection.
+	// MaxInitLen defines the maxinum initial length that we "make" a collection (string, slice, map, chan).
+	// If 0 or negative, we default to a sensible value based on the size of an element in the collection.
 	//
 	// For example, when decoding, a stream may say that it has 2^64 elements.
-	// We should not auto-matically provision a slice of that size, to prevent Out-Of-Memory crash.
+	// We should not auto-matically provision a slice of that length, to prevent Out-Of-Memory crash.
 	// Instead, we provision up to MaxInitLen, fill that up, and start appending after that.
 	MaxInitLen int
 
-	// ReaderBufferSize is the size of the buffer used when reading.
-	//
-	// if > 0, we use a smart buffer internally for performance purposes.
-	ReaderBufferSize int
-
 	// If ErrorIfNoField, return an error when decoding a map
 	// from a codec stream into a struct, and no matching struct field is found.
 	ErrorIfNoField bool
@@ -190,11 +141,6 @@ type DecodeOptions struct {
 	// or is an interface.
 	MapValueReset bool
 
-	// SliceElementReset: on decoding a slice, reset the element to a zero value first.
-	//
-	// concern: if the slice already contained some garbage, we will decode into that garbage.
-	SliceElementReset bool
-
 	// InterfaceReset controls how we decode into an interface.
 	//
 	// By default, when we see a field that is an interface{...},
@@ -215,9 +161,7 @@ type DecodeOptions struct {
 	// look them up from a map (than to allocate them afresh).
 	//
 	// Note: Handles will be smart when using the intern functionality.
-	// Every string should not be interned.
-	// An excellent use-case for interning is struct field names,
-	// or map keys where key type is string.
+	// So everything will not be interned.
 	InternString bool
 
 	// PreferArrayOverSlice controls whether to decode to an array or a slice.
@@ -228,355 +172,20 @@ type DecodeOptions struct {
 	// *Note*: This only applies if using go1.5 and above,
 	// as it requires reflect.ArrayOf support which was absent before go1.5.
 	PreferArrayOverSlice bool
-
-	// DeleteOnNilMapValue controls how to decode a nil value in the stream.
-	//
-	// If true, we will delete the mapping of the key.
-	// Else, just set the mapping to the zero value of the type.
-	DeleteOnNilMapValue bool
 }
 
 // ------------------------------------
 
-type bufioDecReader struct {
-	buf []byte
-	r   io.Reader
-
-	c   int // cursor
-	n   int // num read
-	err error
-
-	tr  []byte
-	trb bool
-	b   [4]byte
-}
-
-func (z *bufioDecReader) reset(r io.Reader) {
-	z.r, z.c, z.n, z.err, z.trb = r, 0, 0, nil, false
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-}
-
-func (z *bufioDecReader) Read(p []byte) (n int, err error) {
-	if z.err != nil {
-		return 0, z.err
-	}
-	p0 := p
-	n = copy(p, z.buf[z.c:])
-	z.c += n
-	if z.c == len(z.buf) {
-		z.c = 0
-	}
-	z.n += n
-	if len(p) == n {
-		if z.c == 0 {
-			z.buf = z.buf[:1]
-			z.buf[0] = p[len(p)-1]
-			z.c = 1
-		}
-		if z.trb {
-			z.tr = append(z.tr, p0[:n]...)
-		}
-		return
-	}
-	p = p[n:]
-	var n2 int
-	// if we are here, then z.buf is all read
-	if len(p) > len(z.buf) {
-		n2, err = decReadFull(z.r, p)
-		n += n2
-		z.n += n2
-		z.err = err
-		// don't return EOF if some bytes were read. keep for next time.
-		if n > 0 && err == io.EOF {
-			err = nil
-		}
-		// always keep last byte in z.buf
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
-		if z.trb {
-			z.tr = append(z.tr, p0[:n]...)
-		}
-		return
-	}
-	// z.c is now 0, and len(p) <= len(z.buf)
-	for len(p) > 0 && z.err == nil {
-		// println("len(p) loop starting ... ")
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, err = z.r.Read(z.buf)
-		if n2 > 0 {
-			if err == io.EOF {
-				err = nil
-			}
-			z.buf = z.buf[:n2]
-			n2 = copy(p, z.buf)
-			z.c = n2
-			n += n2
-			z.n += n2
-			p = p[n2:]
-		}
-		z.err = err
-		// println("... len(p) loop done")
-	}
-	if z.c == 0 {
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
-	}
-	if z.trb {
-		z.tr = append(z.tr, p0[:n]...)
-	}
-	return
-}
-
-func (z *bufioDecReader) ReadByte() (b byte, err error) {
-	z.b[0] = 0
-	_, err = z.Read(z.b[:1])
-	b = z.b[0]
-	return
-}
-
-func (z *bufioDecReader) UnreadByte() (err error) {
-	if z.err != nil {
-		return z.err
-	}
-	if z.c > 0 {
-		z.c--
-		z.n--
-		if z.trb {
-			z.tr = z.tr[:len(z.tr)-1]
-		}
-		return
-	}
-	return errDecUnreadByteNothingToRead
+// ioDecByteScanner implements Read(), ReadByte(...), UnreadByte(...) methods
+// of io.Reader, io.ByteScanner.
+type ioDecByteScanner struct {
+	r  io.Reader
+	l  byte    // last byte
+	ls byte    // last byte status. 0: init-canDoNothing, 1: canRead, 2: canUnread
+	b  [1]byte // tiny buffer for reading single bytes
 }
 
-func (z *bufioDecReader) numread() int {
-	return z.n
-}
-
-func (z *bufioDecReader) readx(n int) (bs []byte) {
-	if n <= 0 || z.err != nil {
-		return
-	}
-	if z.c+n <= len(z.buf) {
-		bs = z.buf[z.c : z.c+n]
-		z.n += n
-		z.c += n
-		if z.trb {
-			z.tr = append(z.tr, bs...)
-		}
-		return
-	}
-	bs = make([]byte, n)
-	_, err := z.Read(bs)
-	if err != nil {
-		panic(err)
-	}
-	return
-}
-
-func (z *bufioDecReader) readb(bs []byte) {
-	_, err := z.Read(bs)
-	if err != nil {
-		panic(err)
-	}
-}
-
-// func (z *bufioDecReader) readn1eof() (b uint8, eof bool) {
-// 	b, err := z.ReadByte()
-// 	if err != nil {
-// 		if err == io.EOF {
-// 			eof = true
-// 		} else {
-// 			panic(err)
-// 		}
-// 	}
-// 	return
-// }
-
-func (z *bufioDecReader) readn1() (b uint8) {
-	b, err := z.ReadByte()
-	if err != nil {
-		panic(err)
-	}
-	return
-}
-
-func (z *bufioDecReader) search(in []byte, accept *bitset256, stop, flag uint8) (token byte, out []byte) {
-	// flag: 1 (skip), 2 (readTo), 4 (readUntil)
-	if flag == 4 {
-		for i := z.c; i < len(z.buf); i++ {
-			if z.buf[i] == stop {
-				token = z.buf[i]
-				z.n = z.n + (i - z.c) - 1
-				i++
-				out = z.buf[z.c:i]
-				if z.trb {
-					z.tr = append(z.tr, z.buf[z.c:i]...)
-				}
-				z.c = i
-				return
-			}
-		}
-	} else {
-		for i := z.c; i < len(z.buf); i++ {
-			if !accept.isset(z.buf[i]) {
-				token = z.buf[i]
-				z.n = z.n + (i - z.c) - 1
-				if flag == 1 {
-					i++
-				} else {
-					out = z.buf[z.c:i]
-				}
-				if z.trb {
-					z.tr = append(z.tr, z.buf[z.c:i]...)
-				}
-				z.c = i
-				return
-			}
-		}
-	}
-	z.n += len(z.buf) - z.c
-	if flag != 1 {
-		out = append(in, z.buf[z.c:]...)
-	}
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
-	}
-	var n2 int
-	if z.err != nil {
-		return
-	}
-	for {
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, z.err = z.r.Read(z.buf)
-		if n2 > 0 && z.err != nil {
-			z.err = nil
-		}
-		z.buf = z.buf[:n2]
-		if flag == 4 {
-			for i := 0; i < n2; i++ {
-				if z.buf[i] == stop {
-					token = z.buf[i]
-					z.n += i - 1
-					i++
-					out = append(out, z.buf[z.c:i]...)
-					if z.trb {
-						z.tr = append(z.tr, z.buf[z.c:i]...)
-					}
-					z.c = i
-					return
-				}
-			}
-		} else {
-			for i := 0; i < n2; i++ {
-				if !accept.isset(z.buf[i]) {
-					token = z.buf[i]
-					z.n += i - 1
-					if flag == 1 {
-						i++
-					}
-					if flag != 1 {
-						out = append(out, z.buf[z.c:i]...)
-					}
-					if z.trb {
-						z.tr = append(z.tr, z.buf[z.c:i]...)
-					}
-					z.c = i
-					return
-				}
-			}
-		}
-		if flag != 1 {
-			out = append(out, z.buf[:n2]...)
-		}
-		z.n += n2
-		if z.err != nil {
-			return
-		}
-		if z.trb {
-			z.tr = append(z.tr, z.buf[:n2]...)
-		}
-	}
-}
-
-func (z *bufioDecReader) skip(accept *bitset256) (token byte) {
-	token, _ = z.search(nil, accept, 0, 1)
-	return
-}
-
-func (z *bufioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
-	_, out = z.search(in, accept, 0, 2)
-	return
-}
-
-func (z *bufioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	_, out = z.search(in, nil, stop, 4)
-	return
-}
-
-func (z *bufioDecReader) unreadn1() {
-	err := z.UnreadByte()
-	if err != nil {
-		panic(err)
-	}
-}
-
-func (z *bufioDecReader) track() {
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-	z.trb = true
-}
-
-func (z *bufioDecReader) stopTrack() (bs []byte) {
-	z.trb = false
-	return z.tr
-}
-
-// ioDecReader is a decReader that reads off an io.Reader.
-//
-// It also has a fallback implementation of ByteScanner if needed.
-type ioDecReader struct {
-	r io.Reader // the reader passed in
-
-	rr io.Reader
-	br io.ByteScanner
-
-	l   byte // last byte
-	ls  byte // last byte status. 0: init-canDoNothing, 1: canRead, 2: canUnread
-	trb bool // tracking bytes turned on
-	_   bool
-	b   [4]byte // tiny buffer for reading single bytes
-
-	x  [scratchByteArrayLen]byte // for: get struct field name, swallow valueTypeBytes, etc
-	n  int                       // num read
-	tr []byte                    // tracking bytes read
-}
-
-func (z *ioDecReader) reset(r io.Reader) {
-	z.r = r
-	z.rr = r
-	z.l, z.ls, z.n, z.trb = 0, 0, 0, false
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-	var ok bool
-	if z.br, ok = r.(io.ByteScanner); !ok {
-		z.br = z
-		z.rr = z
-	}
-}
-
-func (z *ioDecReader) Read(p []byte) (n int, err error) {
-	if len(p) == 0 {
-		return
-	}
+func (z *ioDecByteScanner) Read(p []byte) (n int, err error) {
 	var firstByte bool
 	if z.ls == 1 {
 		z.ls = 2
@@ -602,8 +211,8 @@ func (z *ioDecReader) Read(p []byte) (n int, err error) {
 	return
 }
 
-func (z *ioDecReader) ReadByte() (c byte, err error) {
-	n, err := z.Read(z.b[:1])
+func (z *ioDecByteScanner) ReadByte() (c byte, err error) {
+	n, err := z.Read(z.b[:])
 	if n == 1 {
 		c = z.b[0]
 		if err == io.EOF {
@@ -613,20 +222,30 @@ func (z *ioDecReader) ReadByte() (c byte, err error) {
 	return
 }
 
-func (z *ioDecReader) UnreadByte() (err error) {
-	switch z.ls {
-	case 2:
+func (z *ioDecByteScanner) UnreadByte() (err error) {
+	x := z.ls
+	if x == 0 {
+		err = errors.New("cannot unread - nothing has been read")
+	} else if x == 1 {
+		err = errors.New("cannot unread - last byte has not been read")
+	} else if x == 2 {
 		z.ls = 1
-	case 0:
-		err = errDecUnreadByteNothingToRead
-	case 1:
-		err = errDecUnreadByteLastByteNotRead
-	default:
-		err = errDecUnreadByteUnknown
 	}
 	return
 }
 
+// ioDecReader is a decReader that reads off an io.Reader
+type ioDecReader struct {
+	br decReaderByteScanner
+	// temp byte array re-used internally for efficiency during read.
+	// shares buffer with Decoder, so we keep size of struct within 8 words.
+	x   *[scratchByteArrayLen]byte
+	bs  ioDecByteScanner
+	n   int    // num read
+	tr  []byte // tracking bytes read
+	trb bool
+}
+
 func (z *ioDecReader) numread() int {
 	return z.n
 }
@@ -640,7 +259,7 @@ func (z *ioDecReader) readx(n int) (bs []byte) {
 	} else {
 		bs = make([]byte, n)
 	}
-	if _, err := decReadFull(z.rr, bs); err != nil {
+	if _, err := io.ReadAtLeast(z.br, bs, n); err != nil {
 		panic(err)
 	}
 	z.n += len(bs)
@@ -651,18 +270,31 @@ func (z *ioDecReader) readx(n int) (bs []byte) {
 }
 
 func (z *ioDecReader) readb(bs []byte) {
-	// if len(bs) == 0 {
-	// 	return
-	// }
-	if _, err := decReadFull(z.rr, bs); err != nil {
+	if len(bs) == 0 {
+		return
+	}
+	n, err := io.ReadAtLeast(z.br, bs, len(bs))
+	z.n += n
+	if err != nil {
 		panic(err)
 	}
-	z.n += len(bs)
 	if z.trb {
 		z.tr = append(z.tr, bs...)
 	}
 }
 
+func (z *ioDecReader) readn1() (b uint8) {
+	b, err := z.br.ReadByte()
+	if err != nil {
+		panic(err)
+	}
+	z.n++
+	if z.trb {
+		z.tr = append(z.tr, b)
+	}
+	return b
+}
+
 func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
 	b, err := z.br.ReadByte()
 	if err == nil {
@@ -678,62 +310,6 @@ func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
 	return
 }
 
-func (z *ioDecReader) readn1() (b uint8) {
-	var err error
-	if b, err = z.br.ReadByte(); err == nil {
-		z.n++
-		if z.trb {
-			z.tr = append(z.tr, b)
-		}
-		return
-	}
-	panic(err)
-}
-
-func (z *ioDecReader) skip(accept *bitset256) (token byte) {
-	for {
-		var eof bool
-		token, eof = z.readn1eof()
-		if eof {
-			return
-		}
-		if accept.isset(token) {
-			continue
-		}
-		return
-	}
-}
-
-func (z *ioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
-	out = in
-	for {
-		token, eof := z.readn1eof()
-		if eof {
-			return
-		}
-		if accept.isset(token) {
-			out = append(out, token)
-		} else {
-			z.unreadn1()
-			return
-		}
-	}
-}
-
-func (z *ioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	out = in
-	for {
-		token, eof := z.readn1eof()
-		if eof {
-			panic(io.EOF)
-		}
-		out = append(out, token)
-		if token == stop {
-			return
-		}
-	}
-}
-
 func (z *ioDecReader) unreadn1() {
 	err := z.br.UnreadByte()
 	if err != nil {
@@ -761,7 +337,7 @@ func (z *ioDecReader) stopTrack() (bs []byte) {
 
 // ------------------------------------
 
-var errBytesDecReaderCannotUnread = errors.New("cannot unread last byte read")
+var bytesDecReaderCannotUnreadErr = errors.New("cannot unread last byte read")
 
 // bytesDecReader is a decReader that reads off a byte slice with zero copying
 type bytesDecReader struct {
@@ -784,7 +360,7 @@ func (z *bytesDecReader) numread() int {
 
 func (z *bytesDecReader) unreadn1() {
 	if z.c == 0 || len(z.b) == 0 {
-		panic(errBytesDecReaderCannotUnread)
+		panic(bytesDecReaderCannotUnreadErr)
 	}
 	z.c--
 	z.a++
@@ -810,10 +386,6 @@ func (z *bytesDecReader) readx(n int) (bs []byte) {
 	return
 }
 
-func (z *bytesDecReader) readb(bs []byte) {
-	copy(bs, z.readx(len(bs)))
-}
-
 func (z *bytesDecReader) readn1() (v uint8) {
 	if z.a == 0 {
 		panic(io.EOF)
@@ -824,69 +396,19 @@ func (z *bytesDecReader) readn1() (v uint8) {
 	return
 }
 
-// func (z *bytesDecReader) readn1eof() (v uint8, eof bool) {
-// 	if z.a == 0 {
-// 		eof = true
-// 		return
-// 	}
-// 	v = z.b[z.c]
-// 	z.c++
-// 	z.a--
-// 	return
-// }
-
-func (z *bytesDecReader) skip(accept *bitset256) (token byte) {
-	if z.a == 0 {
-		return
-	}
-	blen := len(z.b)
-	for i := z.c; i < blen; i++ {
-		if !accept.isset(z.b[i]) {
-			token = z.b[i]
-			i++
-			z.a -= (i - z.c)
-			z.c = i
-			return
-		}
-	}
-	z.a, z.c = 0, blen
-	return
-}
-
-func (z *bytesDecReader) readTo(_ []byte, accept *bitset256) (out []byte) {
+func (z *bytesDecReader) readn1eof() (v uint8, eof bool) {
 	if z.a == 0 {
+		eof = true
 		return
 	}
-	blen := len(z.b)
-	for i := z.c; i < blen; i++ {
-		if !accept.isset(z.b[i]) {
-			out = z.b[z.c:i]
-			z.a -= (i - z.c)
-			z.c = i
-			return
-		}
-	}
-	out = z.b[z.c:]
-	z.a, z.c = 0, blen
+	v = z.b[z.c]
+	z.c++
+	z.a--
 	return
 }
 
-func (z *bytesDecReader) readUntil(_ []byte, stop byte) (out []byte) {
-	if z.a == 0 {
-		panic(io.EOF)
-	}
-	blen := len(z.b)
-	for i := z.c; i < blen; i++ {
-		if z.b[i] == stop {
-			i++
-			out = z.b[z.c:i]
-			z.a -= (i - z.c)
-			z.c = i
-			return
-		}
-	}
-	z.a, z.c = 0, blen
-	panic(io.EOF)
+func (z *bytesDecReader) readb(bs []byte) {
+	copy(bs, z.readx(len(bs)))
 }
 
 func (z *bytesDecReader) track() {
@@ -897,66 +419,172 @@ func (z *bytesDecReader) stopTrack() (bs []byte) {
 	return z.b[z.t:z.c]
 }
 
+// ------------------------------------
+
+type decFnInfo struct {
+	d     *Decoder
+	ti    *typeInfo
+	xfFn  Ext
+	xfTag uint64
+	seq   seqType
+}
+
 // ----------------------------------------
 
-// func (d *Decoder) builtin(f *codecFnInfo, rv reflect.Value) {
-// 	d.d.DecodeBuiltin(f.ti.rtid, rv2i(rv))
-// }
+type decFn struct {
+	i decFnInfo
+	f func(*decFnInfo, reflect.Value)
+}
+
+func (f *decFnInfo) builtin(rv reflect.Value) {
+	f.d.d.DecodeBuiltin(f.ti.rtid, rv.Addr().Interface())
+}
+
+func (f *decFnInfo) rawExt(rv reflect.Value) {
+	f.d.d.DecodeExt(rv.Addr().Interface(), 0, nil)
+}
 
-func (d *Decoder) rawExt(f *codecFnInfo, rv reflect.Value) {
-	d.d.DecodeExt(rv2i(rv), 0, nil)
+func (f *decFnInfo) raw(rv reflect.Value) {
+	rv.SetBytes(f.d.raw())
 }
 
-func (d *Decoder) ext(f *codecFnInfo, rv reflect.Value) {
-	d.d.DecodeExt(rv2i(rv), f.xfTag, f.xfFn)
+func (f *decFnInfo) ext(rv reflect.Value) {
+	f.d.d.DecodeExt(rv.Addr().Interface(), f.xfTag, f.xfFn)
 }
 
-func (d *Decoder) selferUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	rv2i(rv).(Selfer).CodecDecodeSelf(d)
+func (f *decFnInfo) getValueForUnmarshalInterface(rv reflect.Value, indir int8) (v interface{}) {
+	if indir == -1 {
+		v = rv.Addr().Interface()
+	} else if indir == 0 {
+		v = rv.Interface()
+	} else {
+		for j := int8(0); j < indir; j++ {
+			if rv.IsNil() {
+				rv.Set(reflect.New(rv.Type().Elem()))
+			}
+			rv = rv.Elem()
+		}
+		v = rv.Interface()
+	}
+	return
 }
 
-func (d *Decoder) binaryUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	bm := rv2i(rv).(encoding.BinaryUnmarshaler)
-	xbs := d.d.DecodeBytes(nil, true)
+func (f *decFnInfo) selferUnmarshal(rv reflect.Value) {
+	f.getValueForUnmarshalInterface(rv, f.ti.csIndir).(Selfer).CodecDecodeSelf(f.d)
+}
+
+func (f *decFnInfo) binaryUnmarshal(rv reflect.Value) {
+	bm := f.getValueForUnmarshalInterface(rv, f.ti.bunmIndir).(encoding.BinaryUnmarshaler)
+	xbs := f.d.d.DecodeBytes(nil, false, true)
 	if fnerr := bm.UnmarshalBinary(xbs); fnerr != nil {
 		panic(fnerr)
 	}
 }
 
-func (d *Decoder) textUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	tm := rv2i(rv).(encoding.TextUnmarshaler)
-	fnerr := tm.UnmarshalText(d.d.DecodeStringAsBytes())
+func (f *decFnInfo) textUnmarshal(rv reflect.Value) {
+	tm := f.getValueForUnmarshalInterface(rv, f.ti.tunmIndir).(encoding.TextUnmarshaler)
+	fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true))
 	if fnerr != nil {
 		panic(fnerr)
 	}
 }
 
-func (d *Decoder) jsonUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	tm := rv2i(rv).(jsonUnmarshaler)
-	// bs := d.d.DecodeBytes(d.b[:], true, true)
+func (f *decFnInfo) jsonUnmarshal(rv reflect.Value) {
+	tm := f.getValueForUnmarshalInterface(rv, f.ti.junmIndir).(jsonUnmarshaler)
+	// bs := f.d.d.DecodeBytes(f.d.b[:], true, true)
 	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
-	fnerr := tm.UnmarshalJSON(d.nextValueBytes())
+	fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
 	if fnerr != nil {
 		panic(fnerr)
 	}
 }
 
-func (d *Decoder) kErr(f *codecFnInfo, rv reflect.Value) {
-	d.errorf("no decoding function defined for kind %v", rv.Kind())
+func (f *decFnInfo) kErr(rv reflect.Value) {
+	f.d.errorf("no decoding function defined for kind %v", rv.Kind())
+}
+
+func (f *decFnInfo) kString(rv reflect.Value) {
+	rv.SetString(f.d.d.DecodeString())
+}
+
+func (f *decFnInfo) kBool(rv reflect.Value) {
+	rv.SetBool(f.d.d.DecodeBool())
+}
+
+func (f *decFnInfo) kInt(rv reflect.Value) {
+	rv.SetInt(f.d.d.DecodeInt(intBitsize))
 }
 
+func (f *decFnInfo) kInt64(rv reflect.Value) {
+	rv.SetInt(f.d.d.DecodeInt(64))
+}
+
+func (f *decFnInfo) kInt32(rv reflect.Value) {
+	rv.SetInt(f.d.d.DecodeInt(32))
+}
+
+func (f *decFnInfo) kInt8(rv reflect.Value) {
+	rv.SetInt(f.d.d.DecodeInt(8))
+}
+
+func (f *decFnInfo) kInt16(rv reflect.Value) {
+	rv.SetInt(f.d.d.DecodeInt(16))
+}
+
+func (f *decFnInfo) kFloat32(rv reflect.Value) {
+	rv.SetFloat(f.d.d.DecodeFloat(true))
+}
+
+func (f *decFnInfo) kFloat64(rv reflect.Value) {
+	rv.SetFloat(f.d.d.DecodeFloat(false))
+}
+
+func (f *decFnInfo) kUint8(rv reflect.Value) {
+	rv.SetUint(f.d.d.DecodeUint(8))
+}
+
+func (f *decFnInfo) kUint64(rv reflect.Value) {
+	rv.SetUint(f.d.d.DecodeUint(64))
+}
+
+func (f *decFnInfo) kUint(rv reflect.Value) {
+	rv.SetUint(f.d.d.DecodeUint(uintBitsize))
+}
+
+func (f *decFnInfo) kUintptr(rv reflect.Value) {
+	rv.SetUint(f.d.d.DecodeUint(uintBitsize))
+}
+
+func (f *decFnInfo) kUint32(rv reflect.Value) {
+	rv.SetUint(f.d.d.DecodeUint(32))
+}
+
+func (f *decFnInfo) kUint16(rv reflect.Value) {
+	rv.SetUint(f.d.d.DecodeUint(16))
+}
+
+// func (f *decFnInfo) kPtr(rv reflect.Value) {
+// 	debugf(">>>>>>> ??? decode kPtr called - shouldn't get called")
+// 	if rv.IsNil() {
+// 		rv.Set(reflect.New(rv.Type().Elem()))
+// 	}
+// 	f.d.decodeValue(rv.Elem())
+// }
+
 // var kIntfCtr uint64
 
-func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
+func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
 	// nil interface:
 	// use some hieristics to decode it appropriately
 	// based on the detected next value in the stream.
-	n := d.naked()
+	d := f.d
 	d.d.DecodeNaked()
+	n := &d.n
 	if n.v == valueTypeNil {
 		return
 	}
 	// We cannot decode non-nil stream value into nil interface with methods (e.g. io.Reader).
+	// if num := f.ti.rt.NumMethod(); num > 0 {
 	if f.ti.numMeth > 0 {
 		d.errorf("cannot decode non-nil codec value into nil %v (%v methods)", f.ti.rt, f.ti.numMeth)
 		return
@@ -964,311 +592,268 @@ func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
 	// var useRvn bool
 	switch n.v {
 	case valueTypeMap:
-		// if json, default to a map type with string keys
-		mtid := d.mtid
-		if mtid == 0 {
-			if d.jsms {
-				mtid = mapStrIntfTypId
-			} else {
-				mtid = mapIntfIntfTypId
-			}
-		}
-		if mtid == mapIntfIntfTypId {
-			n.initContainers()
-			if n.lm < arrayCacheLen {
-				n.ma[n.lm] = nil
-				rvn = n.rma[n.lm]
-				n.lm++
-				d.decode(&n.ma[n.lm-1])
-				n.lm--
-			} else {
-				var v2 map[interface{}]interface{}
-				d.decode(&v2)
-				rvn = reflect.ValueOf(&v2).Elem()
-			}
-		} else if mtid == mapStrIntfTypId { // for json performance
-			n.initContainers()
-			if n.ln < arrayCacheLen {
-				n.na[n.ln] = nil
-				rvn = n.rna[n.ln]
-				n.ln++
-				d.decode(&n.na[n.ln-1])
-				n.ln--
-			} else {
-				var v2 map[string]interface{}
-				d.decode(&v2)
-				rvn = reflect.ValueOf(&v2).Elem()
-			}
+		// if d.h.MapType == nil || d.h.MapType == mapIntfIntfTyp {
+		// } else if d.h.MapType == mapStrIntfTyp { // for json performance
+		// }
+		if d.mtid == 0 || d.mtid == mapIntfIntfTypId {
+			l := len(n.ms)
+			n.ms = append(n.ms, nil)
+			var v2 interface{} = &n.ms[l]
+			d.decode(v2)
+			rvn = reflect.ValueOf(v2).Elem()
+			n.ms = n.ms[:l]
+		} else if d.mtid == mapStrIntfTypId { // for json performance
+			l := len(n.ns)
+			n.ns = append(n.ns, nil)
+			var v2 interface{} = &n.ns[l]
+			d.decode(v2)
+			rvn = reflect.ValueOf(v2).Elem()
+			n.ns = n.ns[:l]
 		} else {
-			if d.mtr {
-				rvn = reflect.New(d.h.MapType)
-				d.decode(rv2i(rvn))
-				rvn = rvn.Elem()
-			} else {
-				rvn = reflect.New(d.h.MapType).Elem()
-				d.decodeValue(rvn, nil, true)
-			}
+			rvn = reflect.New(d.h.MapType).Elem()
+			d.decodeValue(rvn, nil)
 		}
 	case valueTypeArray:
+		// if d.h.SliceType == nil || d.h.SliceType == intfSliceTyp {
 		if d.stid == 0 || d.stid == intfSliceTypId {
-			n.initContainers()
-			if n.ls < arrayCacheLen {
-				n.sa[n.ls] = nil
-				rvn = n.rsa[n.ls]
-				n.ls++
-				d.decode(&n.sa[n.ls-1])
-				n.ls--
-			} else {
-				var v2 []interface{}
-				d.decode(&v2)
-				rvn = reflect.ValueOf(&v2).Elem()
-			}
+			l := len(n.ss)
+			n.ss = append(n.ss, nil)
+			var v2 interface{} = &n.ss[l]
+			d.decode(v2)
+			n.ss = n.ss[:l]
+			rvn = reflect.ValueOf(v2).Elem()
 			if reflectArrayOfSupported && d.stid == 0 && d.h.PreferArrayOverSlice {
-				rvn2 := reflect.New(reflectArrayOf(rvn.Len(), intfTyp)).Elem()
-				reflect.Copy(rvn2, rvn)
-				rvn = rvn2
+				rvn = reflectArrayOf(rvn)
 			}
 		} else {
-			if d.str {
-				rvn = reflect.New(d.h.SliceType)
-				d.decode(rv2i(rvn))
-				rvn = rvn.Elem()
-			} else {
-				rvn = reflect.New(d.h.SliceType).Elem()
-				d.decodeValue(rvn, nil, true)
-			}
+			rvn = reflect.New(d.h.SliceType).Elem()
+			d.decodeValue(rvn, nil)
 		}
 	case valueTypeExt:
 		var v interface{}
 		tag, bytes := n.u, n.l // calling decode below might taint the values
 		if bytes == nil {
-			n.initContainers()
-			if n.li < arrayCacheLen {
-				n.ia[n.li] = nil
-				n.li++
-				d.decode(&n.ia[n.li-1])
-				// v = *(&n.ia[l])
-				n.li--
-				v = n.ia[n.li]
-				n.ia[n.li] = nil
-			} else {
-				d.decode(&v)
-			}
+			l := len(n.is)
+			n.is = append(n.is, nil)
+			v2 := &n.is[l]
+			d.decode(v2)
+			v = *v2
+			n.is = n.is[:l]
 		}
 		bfn := d.h.getExtForTag(tag)
 		if bfn == nil {
 			var re RawExt
 			re.Tag = tag
 			re.Data = detachZeroCopyBytes(d.bytes, nil, bytes)
-			re.Value = v
-			rvn = reflect.ValueOf(&re).Elem()
+			rvn = reflect.ValueOf(re)
 		} else {
 			rvnA := reflect.New(bfn.rt)
+			rvn = rvnA.Elem()
 			if bytes != nil {
-				bfn.ext.ReadExt(rv2i(rvnA), bytes)
+				bfn.ext.ReadExt(rvnA.Interface(), bytes)
 			} else {
-				bfn.ext.UpdateExt(rv2i(rvnA), v)
+				bfn.ext.UpdateExt(rvnA.Interface(), v)
 			}
-			rvn = rvnA.Elem()
 		}
 	case valueTypeNil:
 		// no-op
 	case valueTypeInt:
-		rvn = n.ri
+		rvn = reflect.ValueOf(&n.i).Elem()
 	case valueTypeUint:
-		rvn = n.ru
+		rvn = reflect.ValueOf(&n.u).Elem()
 	case valueTypeFloat:
-		rvn = n.rf
+		rvn = reflect.ValueOf(&n.f).Elem()
 	case valueTypeBool:
-		rvn = n.rb
+		rvn = reflect.ValueOf(&n.b).Elem()
 	case valueTypeString, valueTypeSymbol:
-		rvn = n.rs
+		rvn = reflect.ValueOf(&n.s).Elem()
 	case valueTypeBytes:
-		rvn = n.rl
-	case valueTypeTime:
-		rvn = n.rt
+		rvn = reflect.ValueOf(&n.l).Elem()
+	case valueTypeTimestamp:
+		rvn = reflect.ValueOf(&n.t).Elem()
 	default:
-		panicv.errorf("kInterfaceNaked: unexpected valueType: %d", n.v)
+		panic(fmt.Errorf("kInterfaceNaked: unexpected valueType: %d", n.v))
 	}
 	return
 }
 
-func (d *Decoder) kInterface(f *codecFnInfo, rv reflect.Value) {
+func (f *decFnInfo) kInterface(rv reflect.Value) {
+	// debugf("\t===> kInterface")
+
 	// Note:
 	// A consequence of how kInterface works, is that
 	// if an interface already contains something, we try
 	// to decode into what was there before.
 	// We do not replace with a generic value (as got from decodeNaked).
 
-	// every interface passed here MUST be settable.
 	var rvn reflect.Value
-	if rv.IsNil() || d.h.InterfaceReset {
-		// check if mapping to a type: if so, initialize it and move on
-		rvn = d.h.intf2impl(f.ti.rtid)
+	if rv.IsNil() {
+		rvn = f.kInterfaceNaked()
+		if rvn.IsValid() {
+			rv.Set(rvn)
+		}
+	} else if f.d.h.InterfaceReset {
+		rvn = f.kInterfaceNaked()
 		if rvn.IsValid() {
 			rv.Set(rvn)
 		} else {
-			rvn = d.kInterfaceNaked(f)
-			if rvn.IsValid() {
-				rv.Set(rvn)
-			} else if d.h.InterfaceReset {
-				// reset to zero value based on current type in there.
-				rv.Set(reflect.Zero(rv.Elem().Type()))
-			}
-			return
+			// reset to zero value based on current type in there.
+			rv.Set(reflect.Zero(rv.Elem().Type()))
 		}
 	} else {
-		// now we have a non-nil interface value, meaning it contains a type
 		rvn = rv.Elem()
+		// Note: interface{} is settable, but underlying type may not be.
+		// Consequently, we have to set the reflect.Value directly.
+		// if underlying type is settable (e.g. ptr or interface),
+		// we just decode into it.
+		// Else we create a settable value, decode into it, and set on the interface.
+		if rvn.CanSet() {
+			f.d.decodeValue(rvn, nil)
+		} else {
+			rvn2 := reflect.New(rvn.Type()).Elem()
+			rvn2.Set(rvn)
+			f.d.decodeValue(rvn2, nil)
+			rv.Set(rvn2)
+		}
 	}
-	if d.d.TryDecodeAsNil() {
-		rv.Set(reflect.Zero(rvn.Type()))
-		return
-	}
-
-	// Note: interface{} is settable, but underlying type may not be.
-	// Consequently, we MAY have to create a decodable value out of the underlying value,
-	// decode into it, and reset the interface itself.
-	// fmt.Printf(">>>> kInterface: rvn type: %v, rv type: %v\n", rvn.Type(), rv.Type())
-
-	rvn2, canDecode := isDecodeable(rvn)
-	if canDecode {
-		d.decodeValue(rvn2, nil, true)
-		return
-	}
-
-	rvn2 = reflect.New(rvn.Type()).Elem()
-	rvn2.Set(rvn)
-	d.decodeValue(rvn2, nil, true)
-	rv.Set(rvn2)
-}
-
-func decStructFieldKey(dd decDriver, keyType valueType, b *[decScratchByteArrayLen]byte) (rvkencname []byte) {
-	// use if-else-if, not switch (which compiles to binary-search)
-	// since keyType is typically valueTypeString, branch prediction is pretty good.
-
-	if keyType == valueTypeString {
-		rvkencname = dd.DecodeStringAsBytes()
-	} else if keyType == valueTypeInt {
-		rvkencname = strconv.AppendInt(b[:0], dd.DecodeInt64(), 10)
-	} else if keyType == valueTypeUint {
-		rvkencname = strconv.AppendUint(b[:0], dd.DecodeUint64(), 10)
-	} else if keyType == valueTypeFloat {
-		rvkencname = strconv.AppendFloat(b[:0], dd.DecodeFloat64(), 'f', -1, 64)
-	} else {
-		rvkencname = dd.DecodeStringAsBytes()
-	}
-	return rvkencname
 }
 
-func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
+func (f *decFnInfo) kStruct(rv reflect.Value) {
 	fti := f.ti
+	d := f.d
 	dd := d.d
-	elemsep := d.esep
-	sfn := structFieldNode{v: rv, update: true}
+	cr := d.cr
 	ctyp := dd.ContainerType()
 	if ctyp == valueTypeMap {
 		containerLen := dd.ReadMapStart()
 		if containerLen == 0 {
-			dd.ReadMapEnd()
+			if cr != nil {
+				cr.sendContainerState(containerMapEnd)
+			}
 			return
 		}
-		tisfi := fti.sfiSort
+		tisfi := fti.sfi
 		hasLen := containerLen >= 0
-
-		var rvkencname []byte
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			if elemsep {
-				dd.ReadMapElemKey()
-			}
-			rvkencname = decStructFieldKey(dd, fti.keyType, &d.b)
-			if elemsep {
-				dd.ReadMapElemValue()
+		if hasLen {
+			for j := 0; j < containerLen; j++ {
+				// rvkencname := dd.DecodeString()
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				rvkencname := stringView(dd.DecodeBytes(f.d.b[:], true, true))
+				// rvksi := ti.getForEncName(rvkencname)
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				if k := fti.indexForEncName(rvkencname); k > -1 {
+					si := tisfi[k]
+					if dd.TryDecodeAsNil() {
+						si.setToZeroValue(rv)
+					} else {
+						d.decodeValue(si.field(rv, true), nil)
+					}
+				} else {
+					d.structFieldNotFound(-1, rvkencname)
+				}
 			}
-			if k := fti.indexForEncName(rvkencname); k > -1 {
-				si := tisfi[k]
-				if dd.TryDecodeAsNil() {
-					si.setToZeroValue(rv)
+		} else {
+			for j := 0; !dd.CheckBreak(); j++ {
+				// rvkencname := dd.DecodeString()
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				rvkencname := stringView(dd.DecodeBytes(f.d.b[:], true, true))
+				// rvksi := ti.getForEncName(rvkencname)
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				if k := fti.indexForEncName(rvkencname); k > -1 {
+					si := tisfi[k]
+					if dd.TryDecodeAsNil() {
+						si.setToZeroValue(rv)
+					} else {
+						d.decodeValue(si.field(rv, true), nil)
+					}
 				} else {
-					d.decodeValue(sfn.field(si), nil, true)
+					d.structFieldNotFound(-1, rvkencname)
 				}
-			} else {
-				d.structFieldNotFound(-1, stringView(rvkencname))
 			}
-			// keepAlive4StringView(rvkencnameB) // not needed, as reference is outside loop
 		}
-		dd.ReadMapEnd()
+		if cr != nil {
+			cr.sendContainerState(containerMapEnd)
+		}
 	} else if ctyp == valueTypeArray {
 		containerLen := dd.ReadArrayStart()
 		if containerLen == 0 {
-			dd.ReadArrayEnd()
+			if cr != nil {
+				cr.sendContainerState(containerArrayEnd)
+			}
 			return
 		}
 		// Not much gain from doing it two ways for array.
 		// Arrays are not used as much for structs.
 		hasLen := containerLen >= 0
-		for j, si := range fti.sfiSrc {
-			if (hasLen && j == containerLen) || (!hasLen && dd.CheckBreak()) {
+		for j, si := range fti.sfip {
+			if hasLen {
+				if j == containerLen {
+					break
+				}
+			} else if dd.CheckBreak() {
 				break
 			}
-			if elemsep {
-				dd.ReadArrayElem()
+			if cr != nil {
+				cr.sendContainerState(containerArrayElem)
 			}
 			if dd.TryDecodeAsNil() {
 				si.setToZeroValue(rv)
 			} else {
-				d.decodeValue(sfn.field(si), nil, true)
+				d.decodeValue(si.field(rv, true), nil)
 			}
 		}
-		if containerLen > len(fti.sfiSrc) {
+		if containerLen > len(fti.sfip) {
 			// read remaining values and throw away
-			for j := len(fti.sfiSrc); j < containerLen; j++ {
-				if elemsep {
-					dd.ReadArrayElem()
+			for j := len(fti.sfip); j < containerLen; j++ {
+				if cr != nil {
+					cr.sendContainerState(containerArrayElem)
 				}
 				d.structFieldNotFound(j, "")
 			}
 		}
-		dd.ReadArrayEnd()
+		if cr != nil {
+			cr.sendContainerState(containerArrayEnd)
+		}
 	} else {
-		d.errorstr(errstrOnlyMapOrArrayCanDecodeIntoStruct)
+		f.d.error(onlyMapOrArrayCanDecodeIntoStructErr)
 		return
 	}
 }
 
-func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
+func (f *decFnInfo) kSlice(rv reflect.Value) {
 	// A slice can be set from a map or array in stream.
 	// This way, the order can be kept (as order is lost with map).
 	ti := f.ti
-	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.SendDir) == 0 {
-		d.errorf("receive-only channel cannot be decoded")
-	}
+	d := f.d
 	dd := d.d
-	rtelem0 := ti.elem
+	rtelem0 := ti.rt.Elem()
 	ctyp := dd.ContainerType()
 	if ctyp == valueTypeBytes || ctyp == valueTypeString {
 		// you can only decode bytes or string in the stream into a slice or array of bytes
 		if !(ti.rtid == uint8SliceTypId || rtelem0.Kind() == reflect.Uint8) {
-			d.errorf("bytes/string in stream must decode into slice/array of bytes, not %v", ti.rt)
+			f.d.errorf("bytes or string in the stream must be decoded into a slice or array of bytes, not %v", ti.rt)
 		}
 		if f.seq == seqTypeChan {
-			bs2 := dd.DecodeBytes(nil, true)
-			irv := rv2i(rv)
-			ch, ok := irv.(chan<- byte)
-			if !ok {
-				ch = irv.(chan byte)
-			}
+			bs2 := dd.DecodeBytes(nil, false, true)
+			ch := rv.Interface().(chan<- byte)
 			for _, b := range bs2 {
 				ch <- b
 			}
 		} else {
 			rvbs := rv.Bytes()
-			bs2 := dd.DecodeBytes(rvbs, false)
-			// if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) {
-			if !(len(bs2) > 0 && len(bs2) == len(rvbs) && &bs2[0] == &rvbs[0]) {
+			bs2 := dd.DecodeBytes(rvbs, false, false)
+			if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) {
 				if rv.CanSet() {
 					rv.SetBytes(bs2)
-				} else if len(rvbs) > 0 && len(bs2) > 0 {
+				} else {
 					copy(rvbs, bs2)
 				}
 			}
@@ -1280,225 +865,199 @@ func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 
 	slh, containerLenS := d.decSliceHelperStart() // only expects valueType(Array|Map)
 
-	// an array can never return a nil slice. so no need to check f.array here.
+	// // an array can never return a nil slice. so no need to check f.array here.
 	if containerLenS == 0 {
-		if rv.CanSet() {
-			if f.seq == seqTypeSlice {
-				if rv.IsNil() {
-					rv.Set(reflect.MakeSlice(ti.rt, 0, 0))
-				} else {
-					rv.SetLen(0)
-				}
-			} else if f.seq == seqTypeChan {
-				if rv.IsNil() {
-					rv.Set(reflect.MakeChan(ti.rt, 0))
-				}
+		if f.seq == seqTypeSlice {
+			if rv.IsNil() {
+				rv.Set(reflect.MakeSlice(ti.rt, 0, 0))
+			} else {
+				rv.SetLen(0)
+			}
+		} else if f.seq == seqTypeChan {
+			if rv.IsNil() {
+				rv.Set(reflect.MakeChan(ti.rt, 0))
 			}
 		}
 		slh.End()
 		return
 	}
 
-	rtelem0Size := int(rtelem0.Size())
-	rtElem0Kind := rtelem0.Kind()
-	rtelem0Mut := !isImmutableKind(rtElem0Kind)
 	rtelem := rtelem0
-	rtelemkind := rtelem.Kind()
-	for rtelemkind == reflect.Ptr {
+	for rtelem.Kind() == reflect.Ptr {
 		rtelem = rtelem.Elem()
-		rtelemkind = rtelem.Kind()
-	}
-
-	var fn *codecFn
-
-	var rvCanset = rv.CanSet()
-	var rvChanged bool
-	var rv0 = rv
-	var rv9 reflect.Value
-
-	rvlen := rv.Len()
-	rvcap := rv.Cap()
-	hasLen := containerLenS > 0
-	if hasLen && f.seq == seqTypeSlice {
-		if containerLenS > rvcap {
-			oldRvlenGtZero := rvlen > 0
-			rvlen = decInferLen(containerLenS, d.h.MaxInitLen, int(rtelem0.Size()))
-			if rvlen <= rvcap {
-				if rvCanset {
-					rv.SetLen(rvlen)
-				}
-			} else if rvCanset {
-				rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
-				rvcap = rvlen
-				rvChanged = true
-			} else {
-				d.errorf("cannot decode into non-settable slice")
-			}
-			if rvChanged && oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) {
-				reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap)
-			}
-		} else if containerLenS != rvlen {
-			rvlen = containerLenS
-			if rvCanset {
-				rv.SetLen(rvlen)
-			}
-			// else {
-			// rv = rv.Slice(0, rvlen)
-			// rvChanged = true
-			// d.errorf("cannot decode into non-settable slice")
-			// }
-		}
 	}
+	fn := d.getDecFn(rtelem, true, true)
 
-	// consider creating new element once, and just decoding into it.
-	var rtelem0Zero reflect.Value
-	var rtelem0ZeroValid bool
-	var decodeAsNil bool
-	var j int
-	d.cfer()
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && (f.seq == seqTypeSlice || f.seq == seqTypeChan) && rv.IsNil() {
-			if hasLen {
-				rvlen = decInferLen(containerLenS, d.h.MaxInitLen, rtelem0Size)
-			} else if f.seq == seqTypeSlice {
-				rvlen = decDefSliceCap
-			} else {
-				rvlen = decDefChanCap
-			}
-			if rvCanset {
-				if f.seq == seqTypeSlice {
-					rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
-					rvChanged = true
-				} else { // chan
-					// xdebugf(">>>>>> haslen = %v, make chan of type '%v' with length: %v", hasLen, ti.rt, rvlen)
-					rv = reflect.MakeChan(ti.rt, rvlen)
-					rvChanged = true
-				}
-			} else {
-				d.errorf("cannot decode into non-settable slice")
-			}
-		}
-		slh.ElemContainerState(j)
-		decodeAsNil = dd.TryDecodeAsNil()
+	var rv0, rv9 reflect.Value
+	rv0 = rv
+	rvChanged := false
+
+	// for j := 0; j < containerLenS; j++ {
+	var rvlen int
+	if containerLenS > 0 { // hasLen
 		if f.seq == seqTypeChan {
-			if decodeAsNil {
-				rv.Send(reflect.Zero(rtelem0))
-				continue
+			if rv.IsNil() {
+				rvlen, _ = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size()))
+				rv.Set(reflect.MakeChan(ti.rt, rvlen))
 			}
-			if rtelem0Mut || !rv9.IsValid() { // || (rtElem0Kind == reflect.Ptr && rv9.IsNil()) {
+			// handle chan specially:
+			for j := 0; j < containerLenS; j++ {
 				rv9 = reflect.New(rtelem0).Elem()
+				slh.ElemContainerState(j)
+				d.decodeValue(rv9, fn)
+				rv.Send(rv9)
 			}
-			if fn == nil {
-				fn = d.cf.get(rtelem, true, true)
-			}
-			d.decodeValue(rv9, fn, true)
-			// xdebugf(">>>> rv9 sent on %v during decode: %v, with len=%v, cap=%v", rv.Type(), rv9, rv.Len(), rv.Cap())
-			rv.Send(rv9)
-		} else {
-			// if indefinite, etc, then expand the slice if necessary
-			var decodeIntoBlank bool
-			if j >= rvlen {
+		} else { // slice or array
+			var truncated bool         // says len of sequence is not same as expected number of elements
+			numToRead := containerLenS // if truncated, reset numToRead
+
+			rvcap := rv.Cap()
+			rvlen = rv.Len()
+			if containerLenS > rvcap {
 				if f.seq == seqTypeArray {
-					d.arrayCannotExpand(rvlen, j+1)
-					decodeIntoBlank = true
-				} else { // if f.seq == seqTypeSlice
-					// rv = reflect.Append(rv, reflect.Zero(rtelem0)) // append logic + varargs
-					var rvcap2 int
-					var rvErrmsg2 string
-					rv9, rvcap2, rvChanged, rvErrmsg2 =
-						expandSliceRV(rv, ti.rt, rvCanset, rtelem0Size, 1, rvlen, rvcap)
-					if rvErrmsg2 != "" {
-						d.errorf(rvErrmsg2)
+					d.arrayCannotExpand(rvlen, containerLenS)
+				} else {
+					oldRvlenGtZero := rvlen > 0
+					rvlen, truncated = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size()))
+					if truncated {
+						if rvlen <= rvcap {
+							rv.SetLen(rvlen)
+						} else {
+							rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
+							rvChanged = true
+						}
+					} else {
+						rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
+						rvChanged = true
 					}
-					rvlen++
-					if rvChanged {
-						rv = rv9
-						rvcap = rvcap2
+					if rvChanged && oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) {
+						reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap)
 					}
+					rvcap = rvlen
+				}
+				numToRead = rvlen
+			} else if containerLenS != rvlen {
+				if f.seq == seqTypeSlice {
+					rv.SetLen(containerLenS)
+					rvlen = containerLenS
 				}
 			}
-			if decodeIntoBlank {
-				if !decodeAsNil {
+			j := 0
+			// we read up to the numToRead
+			for ; j < numToRead; j++ {
+				slh.ElemContainerState(j)
+				d.decodeValue(rv.Index(j), fn)
+			}
+
+			// if slice, expand and read up to containerLenS (or EOF) iff truncated
+			// if array, swallow all the rest.
+
+			if f.seq == seqTypeArray {
+				for ; j < containerLenS; j++ {
+					slh.ElemContainerState(j)
 					d.swallow()
 				}
-			} else {
-				rv9 = rv.Index(j)
-				if d.h.SliceElementReset || decodeAsNil {
-					if !rtelem0ZeroValid {
-						rtelem0ZeroValid = true
-						rtelem0Zero = reflect.Zero(rtelem0)
+			} else if truncated { // slice was truncated, as chan NOT in this block
+				for ; j < containerLenS; j++ {
+					rv = expandSliceValue(rv, 1)
+					rv9 = rv.Index(j)
+					if resetSliceElemToZeroValue {
+						rv9.Set(reflect.Zero(rtelem0))
 					}
-					rv9.Set(rtelem0Zero)
+					slh.ElemContainerState(j)
+					d.decodeValue(rv9, fn)
 				}
-				if decodeAsNil {
-					continue
+			}
+		}
+	} else {
+		rvlen = rv.Len()
+		j := 0
+		for ; !dd.CheckBreak(); j++ {
+			if f.seq == seqTypeChan {
+				slh.ElemContainerState(j)
+				rv9 = reflect.New(rtelem0).Elem()
+				d.decodeValue(rv9, fn)
+				rv.Send(rv9)
+			} else {
+				// if indefinite, etc, then expand the slice if necessary
+				var decodeIntoBlank bool
+				if j >= rvlen {
+					if f.seq == seqTypeArray {
+						d.arrayCannotExpand(rvlen, j+1)
+						decodeIntoBlank = true
+					} else { // if f.seq == seqTypeSlice
+						// rv = reflect.Append(rv, reflect.Zero(rtelem0)) // uses append logic, plus varargs
+						rv = expandSliceValue(rv, 1)
+						rv9 = rv.Index(j)
+						// rv.Index(rv.Len() - 1).Set(reflect.Zero(rtelem0))
+						if resetSliceElemToZeroValue {
+							rv9.Set(reflect.Zero(rtelem0))
+						}
+						rvlen++
+						rvChanged = true
+					}
+				} else { // slice or array
+					rv9 = rv.Index(j)
 				}
-
-				if fn == nil {
-					fn = d.cf.get(rtelem, true, true)
+				slh.ElemContainerState(j)
+				if decodeIntoBlank {
+					d.swallow()
+				} else { // seqTypeSlice
+					d.decodeValue(rv9, fn)
 				}
-				d.decodeValue(rv9, fn, true)
 			}
 		}
-	}
-	if f.seq == seqTypeSlice {
-		if j < rvlen {
-			if rv.CanSet() {
+		if f.seq == seqTypeSlice {
+			if j < rvlen {
 				rv.SetLen(j)
-			} else if rvCanset {
-				rv = rv.Slice(0, j)
-				rvChanged = true
-			} // else { d.errorf("kSlice: cannot change non-settable slice") }
-			rvlen = j
-		} else if j == 0 && rv.IsNil() {
-			if rvCanset {
+			} else if j == 0 && rv.IsNil() {
 				rv = reflect.MakeSlice(ti.rt, 0, 0)
 				rvChanged = true
-			} // else { d.errorf("kSlice: cannot change non-settable slice") }
+			}
 		}
 	}
 	slh.End()
 
-	if rvChanged { // infers rvCanset=true, so it can be reset
+	if rvChanged {
 		rv0.Set(rv)
 	}
 }
 
-// func (d *Decoder) kArray(f *codecFnInfo, rv reflect.Value) {
-// 	// d.decodeValueFn(rv.Slice(0, rv.Len()))
-// 	f.kSlice(rv.Slice(0, rv.Len()))
-// }
+func (f *decFnInfo) kArray(rv reflect.Value) {
+	// f.d.decodeValue(rv.Slice(0, rv.Len()))
+	f.kSlice(rv.Slice(0, rv.Len()))
+}
 
-func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
+func (f *decFnInfo) kMap(rv reflect.Value) {
+	d := f.d
 	dd := d.d
 	containerLen := dd.ReadMapStart()
-	elemsep := d.esep
+	cr := d.cr
 	ti := f.ti
 	if rv.IsNil() {
-		rv.Set(makeMapReflect(ti.rt, containerLen))
+		rv.Set(reflect.MakeMap(ti.rt))
 	}
 
 	if containerLen == 0 {
-		dd.ReadMapEnd()
+		if cr != nil {
+			cr.sendContainerState(containerMapEnd)
+		}
 		return
 	}
 
-	ktype, vtype := ti.key, ti.elem
-	ktypeId := rt2id(ktype)
+	ktype, vtype := ti.rt.Key(), ti.rt.Elem()
+	ktypeId := reflect.ValueOf(ktype).Pointer()
 	vtypeKind := vtype.Kind()
-
-	var keyFn, valFn *codecFn
-	var ktypeLo, vtypeLo reflect.Type
-
-	for ktypeLo = ktype; ktypeLo.Kind() == reflect.Ptr; ktypeLo = ktypeLo.Elem() {
+	var keyFn, valFn *decFn
+	var xtyp reflect.Type
+	for xtyp = ktype; xtyp.Kind() == reflect.Ptr; xtyp = xtyp.Elem() {
 	}
-
-	for vtypeLo = vtype; vtypeLo.Kind() == reflect.Ptr; vtypeLo = vtypeLo.Elem() {
+	keyFn = d.getDecFn(xtyp, true, true)
+	for xtyp = vtype; xtyp.Kind() == reflect.Ptr; xtyp = xtyp.Elem() {
 	}
-
+	valFn = d.getDecFn(xtyp, true, true)
 	var mapGet, mapSet bool
-	rvvImmut := isImmutableKind(vtypeKind)
-	if !d.h.MapValueReset {
+	if !f.d.h.MapValueReset {
 		// if pointer, mapGet = true
 		// if interface, mapGet = true if !DecodeNakedAlways (else false)
 		// if builtin, mapGet = false
@@ -1506,124 +1065,118 @@ func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
 		if vtypeKind == reflect.Ptr {
 			mapGet = true
 		} else if vtypeKind == reflect.Interface {
-			if !d.h.InterfaceReset {
+			if !f.d.h.InterfaceReset {
 				mapGet = true
 			}
-		} else if !rvvImmut {
+		} else if !isImmutableKind(vtypeKind) {
 			mapGet = true
 		}
 	}
 
-	var rvk, rvkp, rvv, rvz reflect.Value
-	rvkMut := !isImmutableKind(ktype.Kind()) // if ktype is immutable, then re-use the same rvk.
-	ktypeIsString := ktypeId == stringTypId
-	ktypeIsIntf := ktypeId == intfTypId
-	hasLen := containerLen > 0
-	var kstrbs []byte
-	d.cfer()
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if rvkMut || !rvkp.IsValid() {
-			rvkp = reflect.New(ktype)
-			rvk = rvkp.Elem()
-		}
-		if elemsep {
-			dd.ReadMapElemKey()
-		}
-		if false && dd.TryDecodeAsNil() { // nil cannot be a map key, so disregard this block
-			// Previously, if a nil key, we just ignored the mapped value and continued.
-			// However, that makes the result of encoding and then decoding map[intf]intf{nil:nil}
-			// to be an empty map.
-			// Instead, we treat a nil key as the zero value of the type.
-			rvk.Set(reflect.Zero(ktype))
-		} else if ktypeIsString {
-			kstrbs = dd.DecodeStringAsBytes()
-			rvk.SetString(stringView(kstrbs))
-			// NOTE: if doing an insert, you MUST use a real string (not stringview)
-		} else {
-			if keyFn == nil {
-				keyFn = d.cf.get(ktypeLo, true, true)
+	var rvk, rvv, rvz reflect.Value
+
+	// for j := 0; j < containerLen; j++ {
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			rvk = reflect.New(ktype).Elem()
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-			d.decodeValue(rvk, keyFn, true)
-		}
-		// special case if a byte array.
-		if ktypeIsIntf {
-			if rvk2 := rvk.Elem(); rvk2.IsValid() {
-				if rvk2.Type() == uint8SliceTyp {
-					rvk = reflect.ValueOf(d.string(rvk2.Bytes()))
+			d.decodeValue(rvk, keyFn)
+
+			// special case if a byte array.
+			if ktypeId == intfTypId {
+				rvk = rvk.Elem()
+				if rvk.Type() == uint8SliceTyp {
+					rvk = reflect.ValueOf(d.string(rvk.Bytes()))
+				}
+			}
+			mapSet = true // set to false if u do a get, and its a pointer, and exists
+			if mapGet {
+				rvv = rv.MapIndex(rvk)
+				if rvv.IsValid() {
+					if vtypeKind == reflect.Ptr {
+						mapSet = false
+					}
 				} else {
-					rvk = rvk2
+					if rvz.IsValid() {
+						rvz.Set(reflect.Zero(vtype))
+					} else {
+						rvz = reflect.New(vtype).Elem()
+					}
+					rvv = rvz
 				}
+			} else {
+				if rvz.IsValid() {
+					rvz.Set(reflect.Zero(vtype))
+				} else {
+					rvz = reflect.New(vtype).Elem()
+				}
+				rvv = rvz
 			}
-		}
-
-		if elemsep {
-			dd.ReadMapElemValue()
-		}
-
-		// Brittle, but OK per TryDecodeAsNil() contract.
-		// i.e. TryDecodeAsNil never shares slices with other decDriver procedures
-		if dd.TryDecodeAsNil() {
-			if ktypeIsString {
-				rvk.SetString(d.string(kstrbs))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
-			if d.h.DeleteOnNilMapValue {
-				rv.SetMapIndex(rvk, reflect.Value{})
-			} else {
-				rv.SetMapIndex(rvk, reflect.Zero(vtype))
+			d.decodeValue(rvv, valFn)
+			if mapSet {
+				rv.SetMapIndex(rvk, rvv)
 			}
-			continue
 		}
+	} else {
+		for j := 0; !dd.CheckBreak(); j++ {
+			rvk = reflect.New(ktype).Elem()
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			d.decodeValue(rvk, keyFn)
 
-		mapSet = true // set to false if u do a get, and its a non-nil pointer
-		if mapGet {
-			// mapGet true only in case where kind=Ptr|Interface or kind is otherwise mutable.
-			rvv = rv.MapIndex(rvk)
-			if !rvv.IsValid() {
-				rvv = reflect.New(vtype).Elem()
-			} else if vtypeKind == reflect.Ptr {
-				if rvv.IsNil() {
-					rvv = reflect.New(vtype).Elem()
+			// special case if a byte array.
+			if ktypeId == intfTypId {
+				rvk = rvk.Elem()
+				if rvk.Type() == uint8SliceTyp {
+					rvk = reflect.ValueOf(d.string(rvk.Bytes()))
+				}
+			}
+			mapSet = true // set to false if u do a get, and its a pointer, and exists
+			if mapGet {
+				rvv = rv.MapIndex(rvk)
+				if rvv.IsValid() {
+					if vtypeKind == reflect.Ptr {
+						mapSet = false
+					}
 				} else {
-					mapSet = false
+					if rvz.IsValid() {
+						rvz.Set(reflect.Zero(vtype))
+					} else {
+						rvz = reflect.New(vtype).Elem()
+					}
+					rvv = rvz
 				}
-			} else if vtypeKind == reflect.Interface {
-				// not addressable, and thus not settable.
-				// e MUST create a settable/addressable variant
-				rvv2 := reflect.New(rvv.Type()).Elem()
-				if !rvv.IsNil() {
-					rvv2.Set(rvv)
+			} else {
+				if rvz.IsValid() {
+					rvz.Set(reflect.Zero(vtype))
+				} else {
+					rvz = reflect.New(vtype).Elem()
 				}
-				rvv = rvv2
+				rvv = rvz
 			}
-			// else it is ~mutable, and we can just decode into it directly
-		} else if rvvImmut {
-			if !rvz.IsValid() {
-				rvz = reflect.New(vtype).Elem()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			d.decodeValue(rvv, valFn)
+			if mapSet {
+				rv.SetMapIndex(rvk, rvv)
 			}
-			rvv = rvz
-		} else {
-			rvv = reflect.New(vtype).Elem()
-		}
-
-		// We MUST be done with the stringview of the key, before decoding the value
-		// so that we don't bastardize the reused byte array.
-		if mapSet && ktypeIsString {
-			rvk.SetString(d.string(kstrbs))
-		}
-		if valFn == nil {
-			valFn = d.cf.get(vtypeLo, true, true)
-		}
-		d.decodeValue(rvv, valFn, true)
-		// d.decodeValueFn(rvv, valFn)
-		if mapSet {
-			rv.SetMapIndex(rvk, rvv)
 		}
-		// if ktypeIsString {
-		// 	// keepAlive4StringView(kstrbs) // not needed, as reference is outside loop
-		// }
 	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
 
-	dd.ReadMapEnd()
+type decRtidFn struct {
+	rtid uintptr
+	fn   decFn
 }
 
 // decNaked is used to keep track of the primitives decoded.
@@ -1644,202 +1197,80 @@ func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
 //
 // kInterfaceNaked will ensure that there is no allocation for the common
 // uses.
-
-type decNakedContainers struct {
-	// array/stacks for reducing allocation
-	// keep arrays at the bottom? Chance is that they are not used much.
-	ia [arrayCacheLen]interface{}
-	ma [arrayCacheLen]map[interface{}]interface{}
-	na [arrayCacheLen]map[string]interface{}
-	sa [arrayCacheLen][]interface{}
-
-	// ria [arrayCacheLen]reflect.Value // not needed, as we decode directly into &ia[n]
-	rma, rna, rsa [arrayCacheLen]reflect.Value // reflect.Value mapping to above
-}
-
-func (n *decNakedContainers) init() {
-	for i := 0; i < arrayCacheLen; i++ {
-		// n.ria[i] = reflect.ValueOf(&(n.ia[i])).Elem()
-		n.rma[i] = reflect.ValueOf(&(n.ma[i])).Elem()
-		n.rna[i] = reflect.ValueOf(&(n.na[i])).Elem()
-		n.rsa[i] = reflect.ValueOf(&(n.sa[i])).Elem()
-	}
-}
-
 type decNaked struct {
 	// r RawExt // used for RawExt, uint, []byte.
-
-	// primitives below
 	u uint64
 	i int64
 	f float64
 	l []byte
 	s string
-
-	// ---- cpu cache line boundary?
 	t time.Time
-	b bool
-
-	// state
-	v              valueType
-	li, lm, ln, ls int8
-	inited         bool
-
-	*decNakedContainers
-
-	ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
-
-	// _ [6]uint64 // padding // no padding - rt goes into next cache line
-}
-
-func (n *decNaked) init() {
-	if n.inited {
-		return
-	}
-	n.ru = reflect.ValueOf(&n.u).Elem()
-	n.ri = reflect.ValueOf(&n.i).Elem()
-	n.rf = reflect.ValueOf(&n.f).Elem()
-	n.rl = reflect.ValueOf(&n.l).Elem()
-	n.rs = reflect.ValueOf(&n.s).Elem()
-	n.rt = reflect.ValueOf(&n.t).Elem()
-	n.rb = reflect.ValueOf(&n.b).Elem()
+	b bool
+	v valueType
 
-	n.inited = true
-	// n.rr[] = reflect.ValueOf(&n.)
-}
+	// stacks for reducing allocation
+	is []interface{}
+	ms []map[interface{}]interface{}
+	ns []map[string]interface{}
+	ss [][]interface{}
+	// rs []RawExt
 
-func (n *decNaked) initContainers() {
-	if n.decNakedContainers == nil {
-		n.decNakedContainers = new(decNakedContainers)
-		n.decNakedContainers.init()
-	}
+	// keep arrays at the bottom? Chance is that they are not used much.
+	ia [4]interface{}
+	ma [4]map[interface{}]interface{}
+	na [4]map[string]interface{}
+	sa [4][]interface{}
+	// ra [2]RawExt
 }
 
 func (n *decNaked) reset() {
-	if n == nil {
-		return
+	if n.ss != nil {
+		n.ss = n.ss[:0]
+	}
+	if n.is != nil {
+		n.is = n.is[:0]
+	}
+	if n.ms != nil {
+		n.ms = n.ms[:0]
+	}
+	if n.ns != nil {
+		n.ns = n.ns[:0]
 	}
-	n.li, n.lm, n.ln, n.ls = 0, 0, 0, 0
-}
-
-type rtid2rv struct {
-	rtid uintptr
-	rv   reflect.Value
-}
-
-// --------------
-
-type decReaderSwitch struct {
-	rb bytesDecReader
-	// ---- cpu cache line boundary?
-	ri       *ioDecReader
-	mtr, str bool // whether maptype or slicetype are known types
-
-	be    bool // is binary encoding
-	bytes bool // is bytes reader
-	js    bool // is json handle
-	jsms  bool // is json handle, and MapKeyAsString
-	esep  bool // has elem separators
 }
 
-// TODO: Uncomment after mid-stack inlining enabled in go 1.11
-//
-// func (z *decReaderSwitch) unreadn1() {
-// 	if z.bytes {
-// 		z.rb.unreadn1()
-// 	} else {
-// 		z.ri.unreadn1()
-// 	}
-// }
-// func (z *decReaderSwitch) readx(n int) []byte {
-// 	if z.bytes {
-// 		return z.rb.readx(n)
-// 	}
-// 	return z.ri.readx(n)
-// }
-// func (z *decReaderSwitch) readb(s []byte) {
-// 	if z.bytes {
-// 		z.rb.readb(s)
-// 	} else {
-// 		z.ri.readb(s)
-// 	}
-// }
-// func (z *decReaderSwitch) readn1() uint8 {
-// 	if z.bytes {
-// 		return z.rb.readn1()
-// 	}
-// 	return z.ri.readn1()
-// }
-// func (z *decReaderSwitch) numread() int {
-// 	if z.bytes {
-// 		return z.rb.numread()
-// 	}
-// 	return z.ri.numread()
-// }
-// func (z *decReaderSwitch) track() {
-// 	if z.bytes {
-// 		z.rb.track()
-// 	} else {
-// 		z.ri.track()
-// 	}
-// }
-// func (z *decReaderSwitch) stopTrack() []byte {
-// 	if z.bytes {
-// 		return z.rb.stopTrack()
-// 	}
-// 	return z.ri.stopTrack()
-// }
-// func (z *decReaderSwitch) skip(accept *bitset256) (token byte) {
-// 	if z.bytes {
-// 		return z.rb.skip(accept)
-// 	}
-// 	return z.ri.skip(accept)
-// }
-// func (z *decReaderSwitch) readTo(in []byte, accept *bitset256) (out []byte) {
-// 	if z.bytes {
-// 		return z.rb.readTo(in, accept)
-// 	}
-// 	return z.ri.readTo(in, accept)
-// }
-// func (z *decReaderSwitch) readUntil(in []byte, stop byte) (out []byte) {
-// 	if z.bytes {
-// 		return z.rb.readUntil(in, stop)
-// 	}
-// 	return z.ri.readUntil(in, stop)
-// }
-
 // A Decoder reads and decodes an object from an input stream in the codec format.
 type Decoder struct {
-	panicHdl
 	// hopefully, reduce derefencing cost by laying the decReader inside the Decoder.
 	// Try to put things that go together to fit within a cache line (8 words).
 
 	d decDriver
 	// NOTE: Decoder shouldn't call it's read methods,
 	// as the handler MAY need to do some coordination.
-	r  decReader
+	r decReader
+	// sa [initCollectionCap]decRtidFn
 	h  *BasicHandle
-	bi *bufioDecReader
-	// cache the mapTypeId and sliceTypeId for faster comparisons
-	mtid uintptr
-	stid uintptr
+	hh Handle
+
+	be    bool // is binary encoding
+	bytes bool // is bytes reader
+	js    bool // is json handle
+
+	rb bytesDecReader
+	ri ioDecReader
+	cr containerStateRecv
 
-	// ---- cpu cache line boundary?
-	decReaderSwitch
+	s []decRtidFn
+	f map[uintptr]*decFn
 
-	// ---- cpu cache line boundary?
-	codecFnPooler
-	// cr containerStateRecv
-	n   *decNaked
-	nsp *sync.Pool
-	err error
+	// _  uintptr // for alignment purposes, so next one starts from a cache line
 
-	// ---- cpu cache line boundary?
-	b  [decScratchByteArrayLen]byte // scratch buffer, used by Decoder and xxxEncDrivers
-	is map[string]string            // used for interning strings
+	// cache the mapTypeId and sliceTypeId for faster comparisons
+	mtid uintptr
+	stid uintptr
 
-	// padding - false sharing help // modify 232 if Decoder struct changes.
-	// _ [cacheLineSize - 232%cacheLineSize]byte
+	n  decNaked
+	b  [scratchByteArrayLen]byte
+	is map[string]string // used for interning strings
 }
 
 // NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
@@ -1860,100 +1291,63 @@ func NewDecoderBytes(in []byte, h Handle) *Decoder {
 	return d
 }
 
-var defaultDecNaked decNaked
-
 func newDecoder(h Handle) *Decoder {
-	d := &Decoder{h: h.getBasicHandle(), err: errDecoderNotInitialized}
-	d.hh = h
-	d.be = h.isBinary()
-	// NOTE: do not initialize d.n here. It is lazily initialized in d.naked()
-	var jh *JsonHandle
-	jh, d.js = h.(*JsonHandle)
-	if d.js {
-		d.jsms = jh.MapKeyAsString
-	}
-	d.esep = d.hh.hasElemSeparators()
+	d := &Decoder{hh: h, h: h.getBasicHandle(), be: h.isBinary()}
+	n := &d.n
+	// n.rs = n.ra[:0]
+	n.ms = n.ma[:0]
+	n.is = n.ia[:0]
+	n.ns = n.na[:0]
+	n.ss = n.sa[:0]
+	_, d.js = h.(*JsonHandle)
 	if d.h.InternString {
 		d.is = make(map[string]string, 32)
 	}
 	d.d = h.newDecDriver(d)
-	// d.cr, _ = d.d.(containerStateRecv)
+	d.cr, _ = d.d.(containerStateRecv)
+	// d.d = h.newDecDriver(decReaderT{true, &d.rb, &d.ri})
 	return d
 }
 
 func (d *Decoder) resetCommon() {
 	d.n.reset()
 	d.d.reset()
-	d.err = nil
-	// reset all things which were cached from the Handle, but could change
+	// reset all things which were cached from the Handle,
+	// but could be changed.
 	d.mtid, d.stid = 0, 0
-	d.mtr, d.str = false, false
 	if d.h.MapType != nil {
-		d.mtid = rt2id(d.h.MapType)
-		d.mtr = fastpathAV.index(d.mtid) != -1
+		d.mtid = reflect.ValueOf(d.h.MapType).Pointer()
 	}
 	if d.h.SliceType != nil {
-		d.stid = rt2id(d.h.SliceType)
-		d.str = fastpathAV.index(d.stid) != -1
+		d.stid = reflect.ValueOf(d.h.SliceType).Pointer()
 	}
 }
 
-// Reset the Decoder with a new Reader to decode from,
-// clearing all state from last run(s).
 func (d *Decoder) Reset(r io.Reader) {
-	if r == nil {
-		return
-	}
-	if d.bi == nil {
-		d.bi = new(bufioDecReader)
-	}
-	d.bytes = false
-	if d.h.ReaderBufferSize > 0 {
-		d.bi.buf = make([]byte, 0, d.h.ReaderBufferSize)
-		d.bi.reset(r)
-		d.r = d.bi
-	} else {
-		// d.ri.x = &d.b
-		// d.s = d.sa[:0]
-		if d.ri == nil {
-			d.ri = new(ioDecReader)
-		}
-		d.ri.reset(r)
-		d.r = d.ri
+	d.ri.x = &d.b
+	// d.s = d.sa[:0]
+	d.ri.bs.r = r
+	var ok bool
+	d.ri.br, ok = r.(decReaderByteScanner)
+	if !ok {
+		d.ri.br = &d.ri.bs
 	}
+	d.r = &d.ri
 	d.resetCommon()
 }
 
-// ResetBytes resets the Decoder with a new []byte to decode from,
-// clearing all state from last run(s).
 func (d *Decoder) ResetBytes(in []byte) {
-	if in == nil {
-		return
-	}
-	d.bytes = true
+	// d.s = d.sa[:0]
 	d.rb.reset(in)
 	d.r = &d.rb
 	d.resetCommon()
 }
 
-// naked must be called before each call to .DecodeNaked,
-// as they will use it.
-func (d *Decoder) naked() *decNaked {
-	if d.n == nil {
-		// consider one of:
-		//   - get from sync.Pool  (if GC is frequent, there's no value here)
-		//   - new alloc           (safest. only init'ed if it a naked decode will be done)
-		//   - field in Decoder    (makes the Decoder struct very big)
-		// To support using a decoder where a DecodeNaked is not needed,
-		// we prefer #1 or #2.
-		// d.n = new(decNaked) // &d.nv // new(decNaked) // grab from a sync.Pool
-		// d.n.init()
-		var v interface{}
-		d.nsp, v = pool.decNaked()
-		d.n = v.(*decNaked)
-	}
-	return d.n
-}
+// func (d *Decoder) sendContainerState(c containerState) {
+// 	if d.cr != nil {
+// 		d.cr.sendContainerState(c)
+// 	}
+// }
 
 // Decode decodes the stream from reader and stores the result in the
 // value pointed to by v. v cannot be a nil pointer. v can also be
@@ -2005,282 +1399,424 @@ func (d *Decoder) naked() *decNaked {
 // However, when decoding a stream nil, we reset the destination container
 // to its "zero" value (e.g. nil for slice/map, etc).
 //
-// Note: we allow nil values in the stream anywhere except for map keys.
-// A nil value in the encoded stream where a map key is expected is treated as an error.
 func (d *Decoder) Decode(v interface{}) (err error) {
-	defer d.deferred(&err)
-	d.MustDecode(v)
+	defer panicToErr(&err)
+	d.decode(v)
 	return
 }
 
-// MustDecode is like Decode, but panics if unable to Decode.
-// This provides insight to the code location that triggered the error.
-func (d *Decoder) MustDecode(v interface{}) {
-	// TODO: Top-level: ensure that v is a pointer and not nil.
-	if d.err != nil {
-		panic(d.err)
-	}
-	if d.d.TryDecodeAsNil() {
-		setZero(v)
-	} else {
-		d.decode(v)
-	}
-	d.alwaysAtEnd()
-	// xprintf(">>>>>>>> >>>>>>>> num decFns: %v\n", d.cf.sn)
-}
-
-func (d *Decoder) deferred(err1 *error) {
-	d.alwaysAtEnd()
-	if recoverPanicToErr {
-		if x := recover(); x != nil {
-			panicValToErr(d, x, err1)
-			panicValToErr(d, x, &d.err)
-		}
-	}
-}
-
-func (d *Decoder) alwaysAtEnd() {
-	if d.n != nil {
-		// if n != nil, then nsp != nil (they are always set together)
-		d.nsp.Put(d.n)
-		d.n, d.nsp = nil, nil
-	}
-	d.codecFnPooler.alwaysAtEnd()
+// this is not a smart swallow, as it allocates objects and does unnecessary work.
+func (d *Decoder) swallowViaHammer() {
+	var blank interface{}
+	d.decodeValue(reflect.ValueOf(&blank).Elem(), nil)
 }
 
-// // this is not a smart swallow, as it allocates objects and does unnecessary work.
-// func (d *Decoder) swallowViaHammer() {
-// 	var blank interface{}
-// 	d.decodeValueNoFn(reflect.ValueOf(&blank).Elem())
-// }
-
 func (d *Decoder) swallow() {
 	// smarter decode that just swallows the content
 	dd := d.d
 	if dd.TryDecodeAsNil() {
 		return
 	}
-	elemsep := d.esep
+	cr := d.cr
 	switch dd.ContainerType() {
 	case valueTypeMap:
 		containerLen := dd.ReadMapStart()
-		hasLen := containerLen >= 0
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			// if clenGtEqualZero {if j >= containerLen {break} } else if dd.CheckBreak() {break}
-			if elemsep {
-				dd.ReadMapElemKey()
+		clenGtEqualZero := containerLen >= 0
+		for j := 0; ; j++ {
+			if clenGtEqualZero {
+				if j >= containerLen {
+					break
+				}
+			} else if dd.CheckBreak() {
+				break
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
 			d.swallow()
-			if elemsep {
-				dd.ReadMapElemValue()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
 			d.swallow()
 		}
-		dd.ReadMapEnd()
+		if cr != nil {
+			cr.sendContainerState(containerMapEnd)
+		}
 	case valueTypeArray:
-		containerLen := dd.ReadArrayStart()
-		hasLen := containerLen >= 0
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			if elemsep {
-				dd.ReadArrayElem()
+		containerLenS := dd.ReadArrayStart()
+		clenGtEqualZero := containerLenS >= 0
+		for j := 0; ; j++ {
+			if clenGtEqualZero {
+				if j >= containerLenS {
+					break
+				}
+			} else if dd.CheckBreak() {
+				break
+			}
+			if cr != nil {
+				cr.sendContainerState(containerArrayElem)
 			}
 			d.swallow()
 		}
-		dd.ReadArrayEnd()
+		if cr != nil {
+			cr.sendContainerState(containerArrayEnd)
+		}
 	case valueTypeBytes:
-		dd.DecodeBytes(d.b[:], true)
+		dd.DecodeBytes(d.b[:], false, true)
 	case valueTypeString:
-		dd.DecodeStringAsBytes()
+		dd.DecodeBytes(d.b[:], true, true)
+		// dd.DecodeStringAsBytes(d.b[:])
 	default:
 		// these are all primitives, which we can get from decodeNaked
 		// if RawExt using Value, complete the processing.
-		n := d.naked()
 		dd.DecodeNaked()
-		if n.v == valueTypeExt && n.l == nil {
-			n.initContainers()
-			if n.li < arrayCacheLen {
-				n.ia[n.li] = nil
-				n.li++
-				d.decode(&n.ia[n.li-1])
-				n.ia[n.li-1] = nil
-				n.li--
-			} else {
-				var v2 interface{}
-				d.decode(&v2)
-			}
+		if n := &d.n; n.v == valueTypeExt && n.l == nil {
+			l := len(n.is)
+			n.is = append(n.is, nil)
+			v2 := &n.is[l]
+			d.decode(v2)
+			n.is = n.is[:l]
 		}
 	}
 }
 
-func setZero(iv interface{}) {
-	if iv == nil || definitelyNil(iv) {
-		return
-	}
-	var canDecode bool
-	switch v := iv.(type) {
-	case *string:
-		*v = ""
-	case *bool:
-		*v = false
-	case *int:
-		*v = 0
-	case *int8:
-		*v = 0
-	case *int16:
-		*v = 0
-	case *int32:
-		*v = 0
-	case *int64:
-		*v = 0
-	case *uint:
-		*v = 0
-	case *uint8:
-		*v = 0
-	case *uint16:
-		*v = 0
-	case *uint32:
-		*v = 0
-	case *uint64:
-		*v = 0
-	case *float32:
-		*v = 0
-	case *float64:
-		*v = 0
-	case *[]uint8:
-		*v = nil
-	case *Raw:
-		*v = nil
-	case *time.Time:
-		*v = time.Time{}
-	case reflect.Value:
-		if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
-			v.Set(reflect.Zero(v.Type()))
-		} // TODO: else drain if chan, clear if map, set all to nil if slice???
-	default:
-		if !fastpathDecodeSetZeroTypeSwitch(iv) {
-			v := reflect.ValueOf(iv)
-			if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
-				v.Set(reflect.Zero(v.Type()))
-			} // TODO: else drain if chan, clear if map, set all to nil if slice???
-		}
-	}
+// MustDecode is like Decode, but panics if unable to Decode.
+// This provides insight to the code location that triggered the error.
+func (d *Decoder) MustDecode(v interface{}) {
+	d.decode(v)
 }
 
 func (d *Decoder) decode(iv interface{}) {
-	// check nil and interfaces explicitly,
-	// so that type switches just have a run of constant non-interface types.
-	if iv == nil {
-		d.errorstr(errstrCannotDecodeIntoNil)
-		return
-	}
-	if v, ok := iv.(Selfer); ok {
-		v.CodecDecodeSelf(d)
+	// if ics, ok := iv.(Selfer); ok {
+	// 	ics.CodecDecodeSelf(d)
+	// 	return
+	// }
+
+	if d.d.TryDecodeAsNil() {
+		switch v := iv.(type) {
+		case nil:
+		case *string:
+			*v = ""
+		case *bool:
+			*v = false
+		case *int:
+			*v = 0
+		case *int8:
+			*v = 0
+		case *int16:
+			*v = 0
+		case *int32:
+			*v = 0
+		case *int64:
+			*v = 0
+		case *uint:
+			*v = 0
+		case *uint8:
+			*v = 0
+		case *uint16:
+			*v = 0
+		case *uint32:
+			*v = 0
+		case *uint64:
+			*v = 0
+		case *float32:
+			*v = 0
+		case *float64:
+			*v = 0
+		case *[]uint8:
+			*v = nil
+		case *Raw:
+			*v = nil
+		case reflect.Value:
+			if v.Kind() != reflect.Ptr || v.IsNil() {
+				d.errNotValidPtrValue(v)
+			}
+			// d.chkPtrValue(v)
+			v = v.Elem()
+			if v.IsValid() {
+				v.Set(reflect.Zero(v.Type()))
+			}
+		default:
+			rv := reflect.ValueOf(iv)
+			if rv.Kind() != reflect.Ptr || rv.IsNil() {
+				d.errNotValidPtrValue(rv)
+			}
+			// d.chkPtrValue(rv)
+			rv = rv.Elem()
+			if rv.IsValid() {
+				rv.Set(reflect.Zero(rv.Type()))
+			}
+		}
 		return
 	}
 
 	switch v := iv.(type) {
-	// case nil:
-	// case Selfer:
+	case nil:
+		d.error(cannotDecodeIntoNilErr)
+		return
+
+	case Selfer:
+		v.CodecDecodeSelf(d)
 
 	case reflect.Value:
-		v = d.ensureDecodeable(v)
-		d.decodeValue(v, nil, true)
+		if v.Kind() != reflect.Ptr || v.IsNil() {
+			d.errNotValidPtrValue(v)
+		}
+		// d.chkPtrValue(v)
+		d.decodeValueNotNil(v.Elem(), nil)
 
 	case *string:
 		*v = d.d.DecodeString()
 	case *bool:
 		*v = d.d.DecodeBool()
 	case *int:
-		*v = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
+		*v = int(d.d.DecodeInt(intBitsize))
 	case *int8:
-		*v = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
+		*v = int8(d.d.DecodeInt(8))
 	case *int16:
-		*v = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
+		*v = int16(d.d.DecodeInt(16))
 	case *int32:
-		*v = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
+		*v = int32(d.d.DecodeInt(32))
 	case *int64:
-		*v = d.d.DecodeInt64()
+		*v = d.d.DecodeInt(64)
 	case *uint:
-		*v = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
+		*v = uint(d.d.DecodeUint(uintBitsize))
 	case *uint8:
-		*v = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
+		*v = uint8(d.d.DecodeUint(8))
 	case *uint16:
-		*v = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
+		*v = uint16(d.d.DecodeUint(16))
 	case *uint32:
-		*v = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
+		*v = uint32(d.d.DecodeUint(32))
 	case *uint64:
-		*v = d.d.DecodeUint64()
+		*v = d.d.DecodeUint(64)
 	case *float32:
-		f64 := d.d.DecodeFloat64()
-		if chkOvf.Float32(f64) {
-			d.errorf("float32 overflow: %v", f64)
-		}
-		*v = float32(f64)
+		*v = float32(d.d.DecodeFloat(true))
 	case *float64:
-		*v = d.d.DecodeFloat64()
+		*v = d.d.DecodeFloat(false)
 	case *[]uint8:
-		*v = d.d.DecodeBytes(*v, false)
-	case []uint8:
-		b := d.d.DecodeBytes(v, false)
-		if !(len(b) > 0 && len(b) == len(v) && &b[0] == &v[0]) {
-			copy(v, b)
-		}
-	case *time.Time:
-		*v = d.d.DecodeTime()
+		*v = d.d.DecodeBytes(*v, false, false)
+
 	case *Raw:
-		*v = d.rawBytes()
+		*v = d.raw()
 
 	case *interface{}:
-		d.decodeValue(reflect.ValueOf(iv).Elem(), nil, true)
-		// d.decodeValueNotNil(reflect.ValueOf(iv).Elem())
+		d.decodeValueNotNil(reflect.ValueOf(iv).Elem(), nil)
 
 	default:
 		if !fastpathDecodeTypeSwitch(iv, d) {
-			v := reflect.ValueOf(iv)
-			v = d.ensureDecodeable(v)
-			d.decodeValue(v, nil, false)
-			// d.decodeValueFallback(v)
+			d.decodeI(iv, true, false, false, false)
 		}
 	}
 }
 
-func (d *Decoder) decodeValue(rv reflect.Value, fn *codecFn, chkAll bool) {
+func (d *Decoder) preDecodeValue(rv reflect.Value, tryNil bool) (rv2 reflect.Value, proceed bool) {
+	if tryNil && d.d.TryDecodeAsNil() {
+		// No need to check if a ptr, recursively, to determine
+		// whether to set value to nil.
+		// Just always set value to its zero type.
+		if rv.IsValid() { // rv.CanSet() // always settable, except it's invalid
+			rv.Set(reflect.Zero(rv.Type()))
+		}
+		return
+	}
+
 	// If stream is not containing a nil value, then we can deref to the base
 	// non-pointer value, and decode into that.
-	var rvp reflect.Value
-	var rvpValid bool
-	if rv.Kind() == reflect.Ptr {
-		rvpValid = true
-		for {
-			if rv.IsNil() {
-				rv.Set(reflect.New(rv.Type().Elem()))
-			}
-			rvp = rv
-			rv = rv.Elem()
-			if rv.Kind() != reflect.Ptr {
+	for rv.Kind() == reflect.Ptr {
+		if rv.IsNil() {
+			rv.Set(reflect.New(rv.Type().Elem()))
+		}
+		rv = rv.Elem()
+	}
+	return rv, true
+}
+
+func (d *Decoder) decodeI(iv interface{}, checkPtr, tryNil, checkFastpath, checkCodecSelfer bool) {
+	rv := reflect.ValueOf(iv)
+	if checkPtr {
+		if rv.Kind() != reflect.Ptr || rv.IsNil() {
+			d.errNotValidPtrValue(rv)
+		}
+		// d.chkPtrValue(rv)
+	}
+	rv, proceed := d.preDecodeValue(rv, tryNil)
+	if proceed {
+		fn := d.getDecFn(rv.Type(), checkFastpath, checkCodecSelfer)
+		fn.f(&fn.i, rv)
+	}
+}
+
+func (d *Decoder) decodeValue(rv reflect.Value, fn *decFn) {
+	if rv, proceed := d.preDecodeValue(rv, true); proceed {
+		if fn == nil {
+			fn = d.getDecFn(rv.Type(), true, true)
+		}
+		fn.f(&fn.i, rv)
+	}
+}
+
+func (d *Decoder) decodeValueNotNil(rv reflect.Value, fn *decFn) {
+	if rv, proceed := d.preDecodeValue(rv, false); proceed {
+		if fn == nil {
+			fn = d.getDecFn(rv.Type(), true, true)
+		}
+		fn.f(&fn.i, rv)
+	}
+}
+
+func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *decFn) {
+	rtid := reflect.ValueOf(rt).Pointer()
+
+	// retrieve or register a focus'ed function for this type
+	// to eliminate need to do the retrieval multiple times
+
+	// if d.f == nil && d.s == nil { debugf("---->Creating new dec f map for type: %v\n", rt) }
+	var ok bool
+	if useMapForCodecCache {
+		fn, ok = d.f[rtid]
+	} else {
+		for i := range d.s {
+			v := &(d.s[i])
+			if v.rtid == rtid {
+				fn, ok = &(v.fn), true
 				break
 			}
 		}
 	}
-
-	if fn == nil {
-		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
-		fn = d.cfer().get(rv.Type(), chkAll, true) // chkAll, chkAll)
+	if ok {
+		return
 	}
-	if fn.i.addrD {
-		if rvpValid {
-			fn.fd(d, &fn.i, rvp)
-		} else if rv.CanAddr() {
-			fn.fd(d, &fn.i, rv.Addr())
-		} else if !fn.i.addrF {
-			fn.fd(d, &fn.i, rv)
-		} else {
-			d.errorf("cannot decode into a non-pointer value")
+
+	if useMapForCodecCache {
+		if d.f == nil {
+			d.f = make(map[uintptr]*decFn, initCollectionCap)
+		}
+		fn = new(decFn)
+		d.f[rtid] = fn
+	} else {
+		if d.s == nil {
+			d.s = make([]decRtidFn, 0, initCollectionCap)
 		}
+		d.s = append(d.s, decRtidFn{rtid: rtid})
+		fn = &(d.s[len(d.s)-1]).fn
+	}
+
+	// debugf("\tCreating new dec fn for type: %v\n", rt)
+	ti := d.h.getTypeInfo(rtid, rt)
+	fi := &(fn.i)
+	fi.d = d
+	fi.ti = ti
+
+	// An extension can be registered for any type, regardless of the Kind
+	// (e.g. type BitSet int64, type MyStruct { / * unexported fields * / }, type X []int, etc.
+	//
+	// We can't check if it's an extension byte here first, because the user may have
+	// registered a pointer or non-pointer type, meaning we may have to recurse first
+	// before matching a mapped type, even though the extension byte is already detected.
+	//
+	// NOTE: if decoding into a nil interface{}, we return a non-nil
+	// value except even if the container registers a length of 0.
+	if checkCodecSelfer && ti.cs {
+		fn.f = (*decFnInfo).selferUnmarshal
+	} else if rtid == rawExtTypId {
+		fn.f = (*decFnInfo).rawExt
+	} else if rtid == rawTypId {
+		fn.f = (*decFnInfo).raw
+	} else if d.d.IsBuiltinType(rtid) {
+		fn.f = (*decFnInfo).builtin
+	} else if xfFn := d.h.getExt(rtid); xfFn != nil {
+		fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext
+		fn.f = (*decFnInfo).ext
+	} else if supportMarshalInterfaces && d.be && ti.bunm {
+		fn.f = (*decFnInfo).binaryUnmarshal
+	} else if supportMarshalInterfaces && !d.be && d.js && ti.junm {
+		//If JSON, we should check JSONUnmarshal before textUnmarshal
+		fn.f = (*decFnInfo).jsonUnmarshal
+	} else if supportMarshalInterfaces && !d.be && ti.tunm {
+		fn.f = (*decFnInfo).textUnmarshal
 	} else {
-		fn.fd(d, &fn.i, rv)
+		rk := rt.Kind()
+		if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
+			if rt.PkgPath() == "" {
+				if idx := fastpathAV.index(rtid); idx != -1 {
+					fn.f = fastpathAV[idx].decfn
+				}
+			} else {
+				// use mapping for underlying type if there
+				ok = false
+				var rtu reflect.Type
+				if rk == reflect.Map {
+					rtu = reflect.MapOf(rt.Key(), rt.Elem())
+				} else {
+					rtu = reflect.SliceOf(rt.Elem())
+				}
+				rtuid := reflect.ValueOf(rtu).Pointer()
+				if idx := fastpathAV.index(rtuid); idx != -1 {
+					xfnf := fastpathAV[idx].decfn
+					xrt := fastpathAV[idx].rt
+					fn.f = func(xf *decFnInfo, xrv reflect.Value) {
+						// xfnf(xf, xrv.Convert(xrt))
+						xfnf(xf, xrv.Addr().Convert(reflect.PtrTo(xrt)).Elem())
+					}
+				}
+			}
+		}
+		if fn.f == nil {
+			switch rk {
+			case reflect.String:
+				fn.f = (*decFnInfo).kString
+			case reflect.Bool:
+				fn.f = (*decFnInfo).kBool
+			case reflect.Int:
+				fn.f = (*decFnInfo).kInt
+			case reflect.Int64:
+				fn.f = (*decFnInfo).kInt64
+			case reflect.Int32:
+				fn.f = (*decFnInfo).kInt32
+			case reflect.Int8:
+				fn.f = (*decFnInfo).kInt8
+			case reflect.Int16:
+				fn.f = (*decFnInfo).kInt16
+			case reflect.Float32:
+				fn.f = (*decFnInfo).kFloat32
+			case reflect.Float64:
+				fn.f = (*decFnInfo).kFloat64
+			case reflect.Uint8:
+				fn.f = (*decFnInfo).kUint8
+			case reflect.Uint64:
+				fn.f = (*decFnInfo).kUint64
+			case reflect.Uint:
+				fn.f = (*decFnInfo).kUint
+			case reflect.Uint32:
+				fn.f = (*decFnInfo).kUint32
+			case reflect.Uint16:
+				fn.f = (*decFnInfo).kUint16
+				// case reflect.Ptr:
+				// 	fn.f = (*decFnInfo).kPtr
+			case reflect.Uintptr:
+				fn.f = (*decFnInfo).kUintptr
+			case reflect.Interface:
+				fn.f = (*decFnInfo).kInterface
+			case reflect.Struct:
+				fn.f = (*decFnInfo).kStruct
+			case reflect.Chan:
+				fi.seq = seqTypeChan
+				fn.f = (*decFnInfo).kSlice
+			case reflect.Slice:
+				fi.seq = seqTypeSlice
+				fn.f = (*decFnInfo).kSlice
+			case reflect.Array:
+				fi.seq = seqTypeArray
+				fn.f = (*decFnInfo).kArray
+			case reflect.Map:
+				fn.f = (*decFnInfo).kMap
+			default:
+				fn.f = (*decFnInfo).kErr
+			}
+		}
 	}
-	// return rv
+
+	return
 }
 
 func (d *Decoder) structFieldNotFound(index int, rvkencname string) {
@@ -2303,73 +1839,66 @@ func (d *Decoder) arrayCannotExpand(sliceLen, streamLen int) {
 	}
 }
 
-func isDecodeable(rv reflect.Value) (rv2 reflect.Value, canDecode bool) {
-	switch rv.Kind() {
-	case reflect.Array:
-		return rv, true
-	case reflect.Ptr:
-		if !rv.IsNil() {
-			return rv.Elem(), true
-		}
-	case reflect.Slice, reflect.Chan, reflect.Map:
-		if !rv.IsNil() {
-			return rv, true
-		}
+func (d *Decoder) chkPtrValue(rv reflect.Value) {
+	// We can only decode into a non-nil pointer
+	if rv.Kind() == reflect.Ptr && !rv.IsNil() {
+		return
 	}
-	return
+	d.errNotValidPtrValue(rv)
 }
 
-func (d *Decoder) ensureDecodeable(rv reflect.Value) (rv2 reflect.Value) {
-	// decode can take any reflect.Value that is a inherently addressable i.e.
-	//   - array
-	//   - non-nil chan    (we will SEND to it)
-	//   - non-nil slice   (we will set its elements)
-	//   - non-nil map     (we will put into it)
-	//   - non-nil pointer (we can "update" it)
-	rv2, canDecode := isDecodeable(rv)
-	if canDecode {
-		return
-	}
+func (d *Decoder) errNotValidPtrValue(rv reflect.Value) {
 	if !rv.IsValid() {
-		d.errorstr(errstrCannotDecodeIntoNil)
+		d.error(cannotDecodeIntoNilErr)
 		return
 	}
 	if !rv.CanInterface() {
 		d.errorf("cannot decode into a value without an interface: %v", rv)
 		return
 	}
-	rvi := rv2i(rv)
-	rvk := rv.Kind()
-	d.errorf("cannot decode into value of kind: %v, type: %T, %v", rvk, rvi, rvi)
-	return
+	rvi := rv.Interface()
+	d.errorf("cannot decode into non-pointer or nil pointer. Got: %v, %T, %v", rv.Kind(), rvi, rvi)
+}
+
+func (d *Decoder) error(err error) {
+	panic(err)
+}
+
+func (d *Decoder) errorf(format string, params ...interface{}) {
+	params2 := make([]interface{}, len(params)+1)
+	params2[0] = d.r.numread()
+	copy(params2[1:], params)
+	err := fmt.Errorf("[pos %d]: "+format, params2...)
+	panic(err)
 }
 
-// Possibly get an interned version of a string
-//
-// This should mostly be used for map keys, where the key type is string.
-// This is because keys of a map/struct are typically reused across many objects.
 func (d *Decoder) string(v []byte) (s string) {
-	if d.is == nil {
-		return string(v) // don't return stringView, as we need a real string here.
+	if d.is != nil {
+		s, ok := d.is[string(v)] // no allocation here.
+		if !ok {
+			s = string(v)
+			d.is[s] = s
+		}
+		return s
 	}
-	s, ok := d.is[string(v)] // no allocation here, per go implementation
-	if !ok {
-		s = string(v) // new allocation here
+	return string(v) // don't return stringView, as we need a real string here.
+}
+
+func (d *Decoder) intern(s string) {
+	if d.is != nil {
 		d.is[s] = s
 	}
-	return s
 }
 
 // nextValueBytes returns the next value in the stream as a set of bytes.
-func (d *Decoder) nextValueBytes() (bs []byte) {
+func (d *Decoder) nextValueBytes() []byte {
 	d.d.uncacheRead()
 	d.r.track()
 	d.swallow()
-	bs = d.r.stopTrack()
-	return
+	return d.r.stopTrack()
 }
 
-func (d *Decoder) rawBytes() []byte {
+func (d *Decoder) raw() []byte {
 	// ensure that this is not a view into the bytes
 	// i.e. make new copy always.
 	bs := d.nextValueBytes()
@@ -2378,10 +1907,6 @@ func (d *Decoder) rawBytes() []byte {
 	return bs2
 }
 
-func (d *Decoder) wrapErrstr(v interface{}, err *error) {
-	*err = fmt.Errorf("%s decode error [pos %d]: %v", d.hh.Name(), d.r.numread(), v)
-}
-
 // --------------------------------------------------
 
 // decSliceHelper assists when decoding into a slice, from a map or an array in the stream.
@@ -2395,13 +1920,12 @@ type decSliceHelper struct {
 func (d *Decoder) decSliceHelperStart() (x decSliceHelper, clen int) {
 	dd := d.d
 	ctyp := dd.ContainerType()
-	switch ctyp {
-	case valueTypeArray:
+	if ctyp == valueTypeArray {
 		x.array = true
 		clen = dd.ReadArrayStart()
-	case valueTypeMap:
+	} else if ctyp == valueTypeMap {
 		clen = dd.ReadMapStart() * 2
-	default:
+	} else {
 		d.errorf("only encoded map or array can be decoded into a slice (%d)", ctyp)
 	}
 	// x.ct = ctyp
@@ -2410,20 +1934,30 @@ func (d *Decoder) decSliceHelperStart() (x decSliceHelper, clen int) {
 }
 
 func (x decSliceHelper) End() {
+	cr := x.d.cr
+	if cr == nil {
+		return
+	}
 	if x.array {
-		x.d.d.ReadArrayEnd()
+		cr.sendContainerState(containerArrayEnd)
 	} else {
-		x.d.d.ReadMapEnd()
+		cr.sendContainerState(containerMapEnd)
 	}
 }
 
 func (x decSliceHelper) ElemContainerState(index int) {
+	cr := x.d.cr
+	if cr == nil {
+		return
+	}
 	if x.array {
-		x.d.d.ReadArrayElem()
-	} else if index%2 == 0 {
-		x.d.d.ReadMapElemKey()
+		cr.sendContainerState(containerArrayElem)
 	} else {
-		x.d.d.ReadMapElemValue()
+		if index%2 == 0 {
+			cr.sendContainerState(containerMapKey)
+		} else {
+			cr.sendContainerState(containerMapValue)
+		}
 	}
 }
 
@@ -2439,11 +1973,12 @@ func decByteSlice(r decReader, clen, maxInitLen int, bs []byte) (bsOut []byte) {
 		r.readb(bsOut)
 	} else {
 		// bsOut = make([]byte, clen)
-		len2 := decInferLen(clen, maxInitLen, 1)
+		len2, _ := decInferLen(clen, maxInitLen, 1)
 		bsOut = make([]byte, len2)
 		r.readb(bsOut)
 		for len2 < clen {
-			len3 := decInferLen(clen-len2, maxInitLen, 1)
+			len3, _ := decInferLen(clen-len2, maxInitLen, 1)
+			// fmt.Printf(">>>>> TESTING: in loop: clen: %v, maxInitLen: %v, len2: %v, len3: %v\n", clen, maxInitLen, len2, len3)
 			bs3 := bsOut
 			bsOut = make([]byte, len2+len3)
 			copy(bsOut, bs3)
@@ -2474,14 +2009,11 @@ func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte
 //    - maxlen: max length to be returned.
 //      if <= 0, it is unset, and we infer it based on the unit size
 //    - unit: number of bytes for each element of the collection
-func decInferLen(clen, maxlen, unit int) (rvlen int) {
+func decInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) {
 	// handle when maxlen is not set i.e. <= 0
 	if clen <= 0 {
 		return
 	}
-	if unit == 0 {
-		return clen
-	}
 	if maxlen <= 0 {
 		// no maxlen defined. Use maximum of 256K memory, with a floor of 4K items.
 		// maxlen = 256 * 1024 / unit
@@ -2496,57 +2028,39 @@ func decInferLen(clen, maxlen, unit int) (rvlen int) {
 	}
 	if clen > maxlen {
 		rvlen = maxlen
+		truncated = true
 	} else {
 		rvlen = clen
 	}
 	return
+	// if clen <= 0 {
+	// 	rvlen = 0
+	// } else if maxlen > 0 && clen > maxlen {
+	// 	rvlen = maxlen
+	// 	truncated = true
+	// } else {
+	// 	rvlen = clen
+	// }
+	// return
 }
 
-func expandSliceRV(s reflect.Value, st reflect.Type, canChange bool, stElemSize, num, slen, scap int) (
-	s2 reflect.Value, scap2 int, changed bool, err string) {
-	l1 := slen + num // new slice length
-	if l1 < slen {
-		err = errmsgExpandSliceOverflow
-		return
-	}
-	if l1 <= scap {
-		if s.CanSet() {
-			s.SetLen(l1)
-		} else if canChange {
-			s2 = s.Slice(0, l1)
-			scap2 = scap
-			changed = true
-		} else {
-			err = errmsgExpandSliceCannotChange
-			return
-		}
-		return
-	}
-	if !canChange {
-		err = errmsgExpandSliceCannotChange
-		return
-	}
-	scap2 = growCap(scap, stElemSize, num)
-	s2 = reflect.MakeSlice(st, l1, scap2)
-	changed = true
-	reflect.Copy(s2, s)
-	return
-}
-
-func decReadFull(r io.Reader, bs []byte) (n int, err error) {
-	var nn int
-	for n < len(bs) && err == nil {
-		nn, err = r.Read(bs[n:])
-		if nn > 0 {
-			if err == io.EOF {
-				// leave EOF for next time
-				err = nil
-			}
-			n += nn
-		}
-	}
-
-	// do not do this - it serves no purpose
-	// if n != len(bs) && err == io.EOF { err = io.ErrUnexpectedEOF }
-	return
-}
+// // implement overall decReader wrapping both, for possible use inline:
+// type decReaderT struct {
+// 	bytes bool
+// 	rb    *bytesDecReader
+// 	ri    *ioDecReader
+// }
+//
+// // implement *Decoder as a decReader.
+// // Using decReaderT (defined just above) caused performance degradation
+// // possibly because of constant copying the value,
+// // and some value->interface conversion causing allocation.
+// func (d *Decoder) unreadn1() {
+// 	if d.bytes {
+// 		d.rb.unreadn1()
+// 	} else {
+// 		d.ri.unreadn1()
+// 	}
+// }
+// ... for other methods of decReader.
+// Testing showed that performance improvement was negligible.
diff --git a/vendor/github.com/ugorji/go/codec/decode_go.go b/vendor/github.com/ugorji/go/codec/decode_go.go
new file mode 100644
index 000000000..ba289cef6
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/decode_go.go
@@ -0,0 +1,16 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.5
+
+package codec
+
+import "reflect"
+
+const reflectArrayOfSupported = true
+
+func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) {
+	rvn2 = reflect.New(reflect.ArrayOf(rvn.Len(), intfTyp)).Elem()
+	reflect.Copy(rvn2, rvn)
+	return
+}
diff --git a/vendor/github.com/ugorji/go/codec/decode_go14.go b/vendor/github.com/ugorji/go/codec/decode_go14.go
new file mode 100644
index 000000000..50063bc8f
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/decode_go14.go
@@ -0,0 +1,14 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build !go1.5
+
+package codec
+
+import "reflect"
+
+const reflectArrayOfSupported = false
+
+func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) {
+	panic("reflect.ArrayOf unsupported")
+}
diff --git a/vendor/github.com/ugorji/go/codec/encode.go b/vendor/github.com/ugorji/go/codec/encode.go
index ef4652945..c2cef812e 100644
--- a/vendor/github.com/ugorji/go/codec/encode.go
+++ b/vendor/github.com/ugorji/go/codec/encode.go
@@ -1,24 +1,42 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
 
 import (
-	"bufio"
 	"encoding"
-	"errors"
 	"fmt"
 	"io"
 	"reflect"
 	"sort"
-	"strconv"
 	"sync"
-	"time"
 )
 
-const defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
+const (
+	defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
+)
+
+// AsSymbolFlag defines what should be encoded as symbols.
+type AsSymbolFlag uint8
+
+const (
+	// AsSymbolDefault is default.
+	// Currently, this means only encode struct field names as symbols.
+	// The default is subject to change.
+	AsSymbolDefault AsSymbolFlag = iota
+
+	// AsSymbolAll means encode anything which could be a symbol as a symbol.
+	AsSymbolAll = 0xfe
 
-var errEncoderNotInitialized = errors.New("Encoder not initialized")
+	// AsSymbolNone means do not encode anything as a symbol.
+	AsSymbolNone = 1 << iota
+
+	// AsSymbolMapStringKeys means encode keys in map[string]XXX as symbols.
+	AsSymbolMapStringKeysFlag
+
+	// AsSymbolStructFieldName means encode struct field names as symbols.
+	AsSymbolStructFieldNameFlag
+)
 
 // encWriter abstracts writing to a byte array or to an io.Writer.
 type encWriter interface {
@@ -31,6 +49,8 @@ type encWriter interface {
 
 // encDriver abstracts the actual codec (binc vs msgpack, etc)
 type encDriver interface {
+	IsBuiltinType(rt uintptr) bool
+	EncodeBuiltin(rt uintptr, v interface{})
 	EncodeNil()
 	EncodeInt(i int64)
 	EncodeUint(i uint64)
@@ -40,78 +60,38 @@ type encDriver interface {
 	// encodeExtPreamble(xtag byte, length int)
 	EncodeRawExt(re *RawExt, e *Encoder)
 	EncodeExt(v interface{}, xtag uint64, ext Ext, e *Encoder)
+	EncodeArrayStart(length int)
+	EncodeMapStart(length int)
 	EncodeString(c charEncoding, v string)
-	// EncodeSymbol(v string)
+	EncodeSymbol(v string)
 	EncodeStringBytes(c charEncoding, v []byte)
-	EncodeTime(time.Time)
+	//TODO
 	//encBignum(f *big.Int)
 	//encStringRunes(c charEncoding, v []rune)
-	WriteArrayStart(length int)
-	WriteArrayElem()
-	WriteArrayEnd()
-	WriteMapStart(length int)
-	WriteMapElemKey()
-	WriteMapElemValue()
-	WriteMapEnd()
 
 	reset()
-	atEndOfEncode()
-}
-
-type ioEncStringWriter interface {
-	WriteString(s string) (n int, err error)
 }
 
 type encDriverAsis interface {
 	EncodeAsis(v []byte)
 }
 
-type encDriverNoopContainerWriter struct{}
+type encNoSeparator struct{}
 
-func (encDriverNoopContainerWriter) WriteArrayStart(length int) {}
-func (encDriverNoopContainerWriter) WriteArrayElem()            {}
-func (encDriverNoopContainerWriter) WriteArrayEnd()             {}
-func (encDriverNoopContainerWriter) WriteMapStart(length int)   {}
-func (encDriverNoopContainerWriter) WriteMapElemKey()           {}
-func (encDriverNoopContainerWriter) WriteMapElemValue()         {}
-func (encDriverNoopContainerWriter) WriteMapEnd()               {}
-func (encDriverNoopContainerWriter) atEndOfEncode()             {}
+func (_ encNoSeparator) EncodeEnd() {}
 
-type encDriverTrackContainerWriter struct {
-	c containerState
+type ioEncWriterWriter interface {
+	WriteByte(c byte) error
+	WriteString(s string) (n int, err error)
+	Write(p []byte) (n int, err error)
 }
 
-func (e *encDriverTrackContainerWriter) WriteArrayStart(length int) { e.c = containerArrayStart }
-func (e *encDriverTrackContainerWriter) WriteArrayElem()            { e.c = containerArrayElem }
-func (e *encDriverTrackContainerWriter) WriteArrayEnd()             { e.c = containerArrayEnd }
-func (e *encDriverTrackContainerWriter) WriteMapStart(length int)   { e.c = containerMapStart }
-func (e *encDriverTrackContainerWriter) WriteMapElemKey()           { e.c = containerMapKey }
-func (e *encDriverTrackContainerWriter) WriteMapElemValue()         { e.c = containerMapValue }
-func (e *encDriverTrackContainerWriter) WriteMapEnd()               { e.c = containerMapEnd }
-func (e *encDriverTrackContainerWriter) atEndOfEncode()             {}
-
-// type ioEncWriterWriter interface {
-// 	WriteByte(c byte) error
-// 	WriteString(s string) (n int, err error)
-// 	Write(p []byte) (n int, err error)
-// }
+type ioEncStringWriter interface {
+	WriteString(s string) (n int, err error)
+}
 
-// EncodeOptions captures configuration options during encode.
 type EncodeOptions struct {
-	// WriterBufferSize is the size of the buffer used when writing.
-	//
-	// if > 0, we use a smart buffer internally for performance purposes.
-	WriterBufferSize int
-
-	// ChanRecvTimeout is the timeout used when selecting from a chan.
-	//
-	// Configuring this controls how we receive from a chan during the encoding process.
-	//   - If ==0, we only consume the elements currently available in the chan.
-	//   - if  <0, we consume until the chan is closed.
-	//   - If  >0, we consume until this timeout.
-	ChanRecvTimeout time.Duration
-
-	// StructToArray specifies to encode a struct as an array, and not as a map
+	// Encode a struct as an array, and not as a map
 	StructToArray bool
 
 	// Canonical representation means that encoding a value will always result in the same
@@ -152,191 +132,330 @@ type EncodeOptions struct {
 	// If unset, we error out.
 	Raw bool
 
-	// // AsSymbols defines what should be encoded as symbols.
-	// //
-	// // Encoding as symbols can reduce the encoded size significantly.
-	// //
-	// // However, during decoding, each string to be encoded as a symbol must
-	// // be checked to see if it has been seen before. Consequently, encoding time
-	// // will increase if using symbols, because string comparisons has a clear cost.
-	// //
-	// // Sample values:
-	// //   AsSymbolNone
-	// //   AsSymbolAll
-	// //   AsSymbolMapStringKeys
-	// //   AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
-	// AsSymbols AsSymbolFlag
+	// AsSymbols defines what should be encoded as symbols.
+	//
+	// Encoding as symbols can reduce the encoded size significantly.
+	//
+	// However, during decoding, each string to be encoded as a symbol must
+	// be checked to see if it has been seen before. Consequently, encoding time
+	// will increase if using symbols, because string comparisons has a clear cost.
+	//
+	// Sample values:
+	//   AsSymbolNone
+	//   AsSymbolAll
+	//   AsSymbolMapStringKeys
+	//   AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
+	AsSymbols AsSymbolFlag
 }
 
 // ---------------------------------------------
 
-// ioEncWriter implements encWriter and can write to an io.Writer implementation
-type ioEncWriter struct {
+type simpleIoEncWriterWriter struct {
 	w  io.Writer
-	ww io.Writer
 	bw io.ByteWriter
 	sw ioEncStringWriter
-	fw ioFlusher
-	b  [8]byte
+	bs [1]byte
 }
 
-func (z *ioEncWriter) WriteByte(b byte) (err error) {
-	z.b[0] = b
-	_, err = z.w.Write(z.b[:1])
+func (o *simpleIoEncWriterWriter) WriteByte(c byte) (err error) {
+	if o.bw != nil {
+		return o.bw.WriteByte(c)
+	}
+	// _, err = o.w.Write([]byte{c})
+	o.bs[0] = c
+	_, err = o.w.Write(o.bs[:])
 	return
 }
 
-func (z *ioEncWriter) WriteString(s string) (n int, err error) {
-	return z.w.Write(bytesView(s))
+func (o *simpleIoEncWriterWriter) WriteString(s string) (n int, err error) {
+	if o.sw != nil {
+		return o.sw.WriteString(s)
+	}
+	// return o.w.Write([]byte(s))
+	return o.w.Write(bytesView(s))
+}
+
+func (o *simpleIoEncWriterWriter) Write(p []byte) (n int, err error) {
+	return o.w.Write(p)
+}
+
+// ----------------------------------------
+
+// ioEncWriter implements encWriter and can write to an io.Writer implementation
+type ioEncWriter struct {
+	w ioEncWriterWriter
+	s simpleIoEncWriterWriter
+	// x [8]byte // temp byte array re-used internally for efficiency
 }
 
 func (z *ioEncWriter) writeb(bs []byte) {
-	if _, err := z.ww.Write(bs); err != nil {
+	if len(bs) == 0 {
+		return
+	}
+	n, err := z.w.Write(bs)
+	if err != nil {
 		panic(err)
 	}
+	if n != len(bs) {
+		panic(fmt.Errorf("incorrect num bytes written. Expecting: %v, Wrote: %v", len(bs), n))
+	}
 }
 
 func (z *ioEncWriter) writestr(s string) {
-	if _, err := z.sw.WriteString(s); err != nil {
+	n, err := z.w.WriteString(s)
+	if err != nil {
 		panic(err)
 	}
+	if n != len(s) {
+		panic(fmt.Errorf("incorrect num bytes written. Expecting: %v, Wrote: %v", len(s), n))
+	}
 }
 
 func (z *ioEncWriter) writen1(b byte) {
-	if err := z.bw.WriteByte(b); err != nil {
+	if err := z.w.WriteByte(b); err != nil {
 		panic(err)
 	}
 }
 
-func (z *ioEncWriter) writen2(b1, b2 byte) {
-	var err error
-	if err = z.bw.WriteByte(b1); err == nil {
-		if err = z.bw.WriteByte(b2); err == nil {
-			return
-		}
+func (z *ioEncWriter) writen2(b1 byte, b2 byte) {
+	z.writen1(b1)
+	z.writen1(b2)
+}
+
+func (z *ioEncWriter) atEndOfEncode() {}
+
+// ----------------------------------------
+
+// bytesEncWriter implements encWriter and can write to an byte slice.
+// It is used by Marshal function.
+type bytesEncWriter struct {
+	b   []byte
+	c   int     // cursor
+	out *[]byte // write out on atEndOfEncode
+}
+
+func (z *bytesEncWriter) writeb(s []byte) {
+	if len(s) == 0 {
+		return
 	}
-	panic(err)
+	oc, a := z.growNoAlloc(len(s))
+	if a {
+		z.growAlloc(len(s), oc)
+	}
+	copy(z.b[oc:], s)
 }
 
-// func (z *ioEncWriter) writen5(b1, b2, b3, b4, b5 byte) {
-// 	z.b[0], z.b[1], z.b[2], z.b[3], z.b[4] = b1, b2, b3, b4, b5
-// 	if _, err := z.ww.Write(z.b[:5]); err != nil {
-// 		panic(err)
-// 	}
-// }
+func (z *bytesEncWriter) writestr(s string) {
+	if len(s) == 0 {
+		return
+	}
+	oc, a := z.growNoAlloc(len(s))
+	if a {
+		z.growAlloc(len(s), oc)
+	}
+	copy(z.b[oc:], s)
+}
+
+func (z *bytesEncWriter) writen1(b1 byte) {
+	oc, a := z.growNoAlloc(1)
+	if a {
+		z.growAlloc(1, oc)
+	}
+	z.b[oc] = b1
+}
+
+func (z *bytesEncWriter) writen2(b1 byte, b2 byte) {
+	oc, a := z.growNoAlloc(2)
+	if a {
+		z.growAlloc(2, oc)
+	}
+	z.b[oc+1] = b2
+	z.b[oc] = b1
+}
+
+func (z *bytesEncWriter) atEndOfEncode() {
+	*(z.out) = z.b[:z.c]
+}
+
+// have a growNoalloc(n int), which can be inlined.
+// if allocation is needed, then call growAlloc(n int)
 
-func (z *ioEncWriter) atEndOfEncode() {
-	if z.fw != nil {
-		if err := z.fw.Flush(); err != nil {
-			panic(err)
+func (z *bytesEncWriter) growNoAlloc(n int) (oldcursor int, allocNeeded bool) {
+	oldcursor = z.c
+	z.c = z.c + n
+	if z.c > len(z.b) {
+		if z.c > cap(z.b) {
+			allocNeeded = true
+		} else {
+			z.b = z.b[:cap(z.b)]
 		}
 	}
+	return
+}
+
+func (z *bytesEncWriter) growAlloc(n int, oldcursor int) {
+	// appendslice logic (if cap < 1024, *2, else *1.25): more expensive. many copy calls.
+	// bytes.Buffer model (2*cap + n): much better
+	// bs := make([]byte, 2*cap(z.b)+n)
+	bs := make([]byte, growCap(cap(z.b), 1, n))
+	copy(bs, z.b[:oldcursor])
+	z.b = bs
 }
 
 // ---------------------------------------------
 
-// bytesEncAppender implements encWriter and can write to an byte slice.
-type bytesEncAppender struct {
-	b   []byte
-	out *[]byte
+type encFnInfo struct {
+	e     *Encoder
+	ti    *typeInfo
+	xfFn  Ext
+	xfTag uint64
+	seq   seqType
 }
 
-func (z *bytesEncAppender) writeb(s []byte) {
-	z.b = append(z.b, s...)
+func (f *encFnInfo) builtin(rv reflect.Value) {
+	f.e.e.EncodeBuiltin(f.ti.rtid, rv.Interface())
 }
-func (z *bytesEncAppender) writestr(s string) {
-	z.b = append(z.b, s...)
+
+func (f *encFnInfo) raw(rv reflect.Value) {
+	f.e.raw(rv.Interface().(Raw))
 }
-func (z *bytesEncAppender) writen1(b1 byte) {
-	z.b = append(z.b, b1)
+
+func (f *encFnInfo) rawExt(rv reflect.Value) {
+	// rev := rv.Interface().(RawExt)
+	// f.e.e.EncodeRawExt(&rev, f.e)
+	var re *RawExt
+	if rv.CanAddr() {
+		re = rv.Addr().Interface().(*RawExt)
+	} else {
+		rev := rv.Interface().(RawExt)
+		re = &rev
+	}
+	f.e.e.EncodeRawExt(re, f.e)
 }
-func (z *bytesEncAppender) writen2(b1, b2 byte) {
-	z.b = append(z.b, b1, b2)
+
+func (f *encFnInfo) ext(rv reflect.Value) {
+	// if this is a struct|array and it was addressable, then pass the address directly (not the value)
+	if k := rv.Kind(); (k == reflect.Struct || k == reflect.Array) && rv.CanAddr() {
+		rv = rv.Addr()
+	}
+	f.e.e.EncodeExt(rv.Interface(), f.xfTag, f.xfFn, f.e)
 }
-func (z *bytesEncAppender) atEndOfEncode() {
-	*(z.out) = z.b
+
+func (f *encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v interface{}, proceed bool) {
+	if indir == 0 {
+		v = rv.Interface()
+	} else if indir == -1 {
+		// If a non-pointer was passed to Encode(), then that value is not addressable.
+		// Take addr if addressable, else copy value to an addressable value.
+		if rv.CanAddr() {
+			v = rv.Addr().Interface()
+		} else {
+			rv2 := reflect.New(rv.Type())
+			rv2.Elem().Set(rv)
+			v = rv2.Interface()
+			// fmt.Printf("rv.Type: %v, rv2.Type: %v, v: %v\n", rv.Type(), rv2.Type(), v)
+		}
+	} else {
+		for j := int8(0); j < indir; j++ {
+			if rv.IsNil() {
+				f.e.e.EncodeNil()
+				return
+			}
+			rv = rv.Elem()
+		}
+		v = rv.Interface()
+	}
+	return v, true
 }
-func (z *bytesEncAppender) reset(in []byte, out *[]byte) {
-	z.b = in[:0]
-	z.out = out
+
+func (f *encFnInfo) selferMarshal(rv reflect.Value) {
+	if v, proceed := f.getValueForMarshalInterface(rv, f.ti.csIndir); proceed {
+		v.(Selfer).CodecEncodeSelf(f.e)
+	}
 }
 
-// ---------------------------------------------
+func (f *encFnInfo) binaryMarshal(rv reflect.Value) {
+	if v, proceed := f.getValueForMarshalInterface(rv, f.ti.bmIndir); proceed {
+		bs, fnerr := v.(encoding.BinaryMarshaler).MarshalBinary()
+		f.e.marshal(bs, fnerr, false, c_RAW)
+	}
+}
 
-func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeRawExt(rv2i(rv).(*RawExt), e)
+func (f *encFnInfo) textMarshal(rv reflect.Value) {
+	if v, proceed := f.getValueForMarshalInterface(rv, f.ti.tmIndir); proceed {
+		// debugf(">>>> encoding.TextMarshaler: %T", rv.Interface())
+		bs, fnerr := v.(encoding.TextMarshaler).MarshalText()
+		f.e.marshal(bs, fnerr, false, c_UTF8)
+	}
+}
+
+func (f *encFnInfo) jsonMarshal(rv reflect.Value) {
+	if v, proceed := f.getValueForMarshalInterface(rv, f.ti.jmIndir); proceed {
+		bs, fnerr := v.(jsonMarshaler).MarshalJSON()
+		f.e.marshal(bs, fnerr, true, c_UTF8)
+	}
 }
 
-func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeExt(rv2i(rv), f.xfTag, f.xfFn, e)
+func (f *encFnInfo) kBool(rv reflect.Value) {
+	f.e.e.EncodeBool(rv.Bool())
 }
 
-func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
-	rv2i(rv).(Selfer).CodecEncodeSelf(e)
+func (f *encFnInfo) kString(rv reflect.Value) {
+	f.e.e.EncodeString(c_UTF8, rv.String())
 }
 
-func (e *Encoder) binaryMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(encoding.BinaryMarshaler).MarshalBinary()
-	e.marshal(bs, fnerr, false, cRAW)
+func (f *encFnInfo) kFloat64(rv reflect.Value) {
+	f.e.e.EncodeFloat64(rv.Float())
 }
 
-func (e *Encoder) textMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(encoding.TextMarshaler).MarshalText()
-	e.marshal(bs, fnerr, false, cUTF8)
+func (f *encFnInfo) kFloat32(rv reflect.Value) {
+	f.e.e.EncodeFloat32(float32(rv.Float()))
 }
 
-func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
-	e.marshal(bs, fnerr, true, cUTF8)
+func (f *encFnInfo) kInt(rv reflect.Value) {
+	f.e.e.EncodeInt(rv.Int())
 }
 
-func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
-	e.rawBytes(rv2i(rv).(Raw))
+func (f *encFnInfo) kUint(rv reflect.Value) {
+	f.e.e.EncodeUint(rv.Uint())
 }
 
-func (e *Encoder) kInvalid(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeNil()
+func (f *encFnInfo) kInvalid(rv reflect.Value) {
+	f.e.e.EncodeNil()
 }
 
-func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
-	e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
+func (f *encFnInfo) kErr(rv reflect.Value) {
+	f.e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
 }
 
-func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
+func (f *encFnInfo) kSlice(rv reflect.Value) {
 	ti := f.ti
-	ee := e.e
 	// array may be non-addressable, so we have to manage with care
 	//   (don't call rv.Bytes, rv.Slice, etc).
 	// E.g. type struct S{B [2]byte};
 	//   Encode(S{}) will bomb on "panic: slice of unaddressable array".
+	e := f.e
 	if f.seq != seqTypeArray {
 		if rv.IsNil() {
-			ee.EncodeNil()
+			e.e.EncodeNil()
 			return
 		}
 		// If in this method, then there was no extension function defined.
 		// So it's okay to treat as []byte.
 		if ti.rtid == uint8SliceTypId {
-			ee.EncodeStringBytes(cRAW, rv.Bytes())
+			e.e.EncodeStringBytes(c_RAW, rv.Bytes())
 			return
 		}
 	}
-	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.RecvDir) == 0 {
-		e.errorf("send-only channel cannot be encoded")
-	}
-	elemsep := e.esep
-	rtelem := ti.elem
-	rtelemIsByte := uint8TypId == rt2id(rtelem) // NOT rtelem.Kind() == reflect.Uint8
-	var l int
-	// if a slice, array or chan of bytes, treat specially
-	if rtelemIsByte {
+	cr := e.cr
+	rtelem := ti.rt.Elem()
+	l := rv.Len()
+	if ti.rtid == uint8SliceTypId || rtelem.Kind() == reflect.Uint8 {
 		switch f.seq {
-		case seqTypeSlice:
-			ee.EncodeStringBytes(cRAW, rv.Bytes())
 		case seqTypeArray:
-			l = rv.Len()
+			// if l == 0 { e.e.encodeStringBytes(c_RAW, nil) } else
 			if rv.CanAddr() {
-				ee.EncodeStringBytes(cRAW, rv.Slice(0, l).Bytes())
+				e.e.EncodeStringBytes(c_RAW, rv.Slice(0, l).Bytes())
 			} else {
 				var bs []byte
 				if l <= cap(e.b) {
@@ -345,263 +464,116 @@ func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 					bs = make([]byte, l)
 				}
 				reflect.Copy(reflect.ValueOf(bs), rv)
-				ee.EncodeStringBytes(cRAW, bs)
+				// TODO: Test that reflect.Copy works instead of manual one-by-one
+				// for i := 0; i < l; i++ {
+				// 	bs[i] = byte(rv.Index(i).Uint())
+				// }
+				e.e.EncodeStringBytes(c_RAW, bs)
 			}
+		case seqTypeSlice:
+			e.e.EncodeStringBytes(c_RAW, rv.Bytes())
 		case seqTypeChan:
+			bs := e.b[:0]
 			// do not use range, so that the number of elements encoded
 			// does not change, and encoding does not hang waiting on someone to close chan.
-			// for b := range rv2i(rv).(<-chan byte) { bs = append(bs, b) }
-			// ch := rv2i(rv).(<-chan byte) // fix error - that this is a chan byte, not a <-chan byte.
-
-			if rv.IsNil() {
-				ee.EncodeNil()
-				break
-			}
-			bs := e.b[:0]
-			irv := rv2i(rv)
-			ch, ok := irv.(<-chan byte)
-			if !ok {
-				ch = irv.(chan byte)
-			}
-
-		L1:
-			switch timeout := e.h.ChanRecvTimeout; {
-			case timeout == 0: // only consume available
-				for {
-					select {
-					case b := <-ch:
-						bs = append(bs, b)
-					default:
-						break L1
-					}
-				}
-			case timeout > 0: // consume until timeout
-				tt := time.NewTimer(timeout)
-				for {
-					select {
-					case b := <-ch:
-						bs = append(bs, b)
-					case <-tt.C:
-						// close(tt.C)
-						break L1
-					}
-				}
-			default: // consume until close
-				for b := range ch {
-					bs = append(bs, b)
-				}
+			// for b := range rv.Interface().(<-chan byte) {
+			// 	bs = append(bs, b)
+			// }
+			ch := rv.Interface().(<-chan byte)
+			for i := 0; i < l; i++ {
+				bs = append(bs, <-ch)
 			}
-
-			ee.EncodeStringBytes(cRAW, bs)
+			e.e.EncodeStringBytes(c_RAW, bs)
 		}
 		return
 	}
 
-	// if chan, consume chan into a slice, and work off that slice.
-	var rvcs reflect.Value
-	if f.seq == seqTypeChan {
-		rvcs = reflect.Zero(reflect.SliceOf(rtelem))
-		timeout := e.h.ChanRecvTimeout
-		if timeout < 0 { // consume until close
-			for {
-				recv, recvOk := rv.Recv()
-				if !recvOk {
-					break
-				}
-				rvcs = reflect.Append(rvcs, recv)
-			}
-		} else {
-			cases := make([]reflect.SelectCase, 2)
-			cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
-			if timeout == 0 {
-				cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
-			} else {
-				tt := time.NewTimer(timeout)
-				cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tt.C)}
-			}
-			for {
-				chosen, recv, recvOk := reflect.Select(cases)
-				if chosen == 1 || !recvOk {
-					break
-				}
-				rvcs = reflect.Append(rvcs, recv)
-			}
-		}
-		rv = rvcs // TODO: ensure this doesn't mess up anywhere that rv of kind chan is expected
-	}
-
-	l = rv.Len()
 	if ti.mbs {
 		if l%2 == 1 {
 			e.errorf("mapBySlice requires even slice length, but got %v", l)
 			return
 		}
-		ee.WriteMapStart(l / 2)
+		e.e.EncodeMapStart(l / 2)
 	} else {
-		ee.WriteArrayStart(l)
+		e.e.EncodeArrayStart(l)
 	}
 
 	if l > 0 {
-		var fn *codecFn
 		for rtelem.Kind() == reflect.Ptr {
 			rtelem = rtelem.Elem()
 		}
 		// if kind is reflect.Interface, do not pre-determine the
 		// encoding type, because preEncodeValue may break it down to
 		// a concrete type and kInterface will bomb.
+		var fn *encFn
 		if rtelem.Kind() != reflect.Interface {
-			fn = e.cfer().get(rtelem, true, true)
+			rtelemid := reflect.ValueOf(rtelem).Pointer()
+			fn = e.getEncFn(rtelemid, rtelem, true, true)
 		}
+		// TODO: Consider perf implication of encoding odd index values as symbols if type is string
 		for j := 0; j < l; j++ {
-			if elemsep {
+			if cr != nil {
 				if ti.mbs {
 					if j%2 == 0 {
-						ee.WriteMapElemKey()
+						cr.sendContainerState(containerMapKey)
 					} else {
-						ee.WriteMapElemValue()
+						cr.sendContainerState(containerMapValue)
 					}
 				} else {
-					ee.WriteArrayElem()
+					cr.sendContainerState(containerArrayElem)
 				}
 			}
-			e.encodeValue(rv.Index(j), fn, true)
+			if f.seq == seqTypeChan {
+				if rv2, ok2 := rv.Recv(); ok2 {
+					e.encodeValue(rv2, fn)
+				} else {
+					e.encode(nil) // WE HAVE TO DO SOMETHING, so nil if nothing received.
+				}
+			} else {
+				e.encodeValue(rv.Index(j), fn)
+			}
 		}
 	}
 
-	if ti.mbs {
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayEnd()
-	}
-}
-
-func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
-	fti := f.ti
-	elemsep := e.esep
-	tisfi := fti.sfiSrc
-	toMap := !(fti.toArray || e.h.StructToArray)
-	if toMap {
-		tisfi = fti.sfiSort
-	}
-	ee := e.e
-
-	sfn := structFieldNode{v: rv, update: false}
-	if toMap {
-		ee.WriteMapStart(len(tisfi))
-		if elemsep {
-			for _, si := range tisfi {
-				ee.WriteMapElemKey()
-				// ee.EncodeString(cUTF8, si.encName)
-				encStructFieldKey(ee, fti.keyType, si.encName)
-				ee.WriteMapElemValue()
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		} else {
-			for _, si := range tisfi {
-				// ee.EncodeString(cUTF8, si.encName)
-				encStructFieldKey(ee, fti.keyType, si.encName)
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		}
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayStart(len(tisfi))
-		if elemsep {
-			for _, si := range tisfi {
-				ee.WriteArrayElem()
-				e.encodeValue(sfn.field(si), nil, true)
-			}
+	if cr != nil {
+		if ti.mbs {
+			cr.sendContainerState(containerMapEnd)
 		} else {
-			for _, si := range tisfi {
-				e.encodeValue(sfn.field(si), nil, true)
-			}
+			cr.sendContainerState(containerArrayEnd)
 		}
-		ee.WriteArrayEnd()
 	}
 }
 
-func encStructFieldKey(ee encDriver, keyType valueType, s string) {
-	var m must
-
-	// use if-else-if, not switch (which compiles to binary-search)
-	// since keyType is typically valueTypeString, branch prediction is pretty good.
-
-	if keyType == valueTypeString {
-		ee.EncodeString(cUTF8, s)
-	} else if keyType == valueTypeInt {
-		ee.EncodeInt(m.Int(strconv.ParseInt(s, 10, 64)))
-	} else if keyType == valueTypeUint {
-		ee.EncodeUint(m.Uint(strconv.ParseUint(s, 10, 64)))
-	} else if keyType == valueTypeFloat {
-		ee.EncodeFloat64(m.Float(strconv.ParseFloat(s, 64)))
-	} else {
-		ee.EncodeString(cUTF8, s)
-	}
-}
-
-func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
+func (f *encFnInfo) kStruct(rv reflect.Value) {
 	fti := f.ti
-	elemsep := e.esep
-	tisfi := fti.sfiSrc
+	e := f.e
+	cr := e.cr
+	tisfi := fti.sfip
 	toMap := !(fti.toArray || e.h.StructToArray)
-	// if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
-	if toMap {
-		tisfi = fti.sfiSort
-	}
-	newlen := len(fti.sfiSort)
-	ee := e.e
+	newlen := len(fti.sfi)
 
 	// Use sync.Pool to reduce allocating slices unnecessarily.
 	// The cost of sync.Pool is less than the cost of new allocation.
-	//
-	// Each element of the array pools one of encStructPool(8|16|32|64).
-	// It allows the re-use of slices up to 64 in length.
-	// A performance cost of encoding structs was collecting
-	// which values were empty and should be omitted.
-	// We needed slices of reflect.Value and string to collect them.
-	// This shared pool reduces the amount of unnecessary creation we do.
-	// The cost is that of locking sometimes, but sync.Pool is efficient
-	// enough to reduce thread contention.
-
-	var spool *sync.Pool
-	var poolv interface{}
-	var fkvs []stringRv
-	// fmt.Printf(">>>>>>>>>>>>>> encode.kStruct: newlen: %d\n", newlen)
-	if newlen <= 8 {
-		spool, poolv = pool.stringRv8()
-		fkvs = poolv.(*[8]stringRv)[:newlen]
-	} else if newlen <= 16 {
-		spool, poolv = pool.stringRv16()
-		fkvs = poolv.(*[16]stringRv)[:newlen]
-	} else if newlen <= 32 {
-		spool, poolv = pool.stringRv32()
-		fkvs = poolv.(*[32]stringRv)[:newlen]
-	} else if newlen <= 64 {
-		spool, poolv = pool.stringRv64()
-		fkvs = poolv.(*[64]stringRv)[:newlen]
-	} else if newlen <= 128 {
-		spool, poolv = pool.stringRv128()
-		fkvs = poolv.(*[128]stringRv)[:newlen]
-	} else {
-		fkvs = make([]stringRv, newlen)
-	}
+	pool, poolv, fkvs := encStructPoolGet(newlen)
 
+	// if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
+	if toMap {
+		tisfi = fti.sfi
+	}
 	newlen = 0
 	var kv stringRv
 	recur := e.h.RecursiveEmptyCheck
-	sfn := structFieldNode{v: rv, update: false}
 	for _, si := range tisfi {
-		// kv.r = si.field(rv, false)
-		kv.r = sfn.field(si)
+		kv.r = si.field(rv, false)
 		if toMap {
-			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
+			if si.omitEmpty && isEmptyValue(kv.r, recur, recur) {
 				continue
 			}
 			kv.v = si.encName
 		} else {
 			// use the zero value.
 			// if a reference or struct, set to nil (so you do not output too much)
-			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
+			if si.omitEmpty && isEmptyValue(kv.r, recur, recur) {
 				switch kv.r.Kind() {
 				case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
 					kv.r = reflect.Value{} //encode as nil
@@ -612,64 +584,91 @@ func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 		newlen++
 	}
 
+	// debugf(">>>> kStruct: newlen: %v", newlen)
+	// sep := !e.be
+	ee := e.e //don't dereference every time
+
 	if toMap {
-		ee.WriteMapStart(newlen)
-		if elemsep {
-			for j := 0; j < newlen; j++ {
-				kv = fkvs[j]
-				ee.WriteMapElemKey()
-				// ee.EncodeString(cUTF8, kv.v)
-				encStructFieldKey(ee, fti.keyType, kv.v)
-				ee.WriteMapElemValue()
-				e.encodeValue(kv.r, nil, true)
+		ee.EncodeMapStart(newlen)
+		// asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0
+		asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0
+		for j := 0; j < newlen; j++ {
+			kv = fkvs[j]
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for j := 0; j < newlen; j++ {
-				kv = fkvs[j]
-				// ee.EncodeString(cUTF8, kv.v)
-				encStructFieldKey(ee, fti.keyType, kv.v)
-				e.encodeValue(kv.r, nil, true)
+			if asSymbols {
+				ee.EncodeSymbol(kv.v)
+			} else {
+				ee.EncodeString(c_UTF8, kv.v)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encodeValue(kv.r, nil)
+		}
+		if cr != nil {
+			cr.sendContainerState(containerMapEnd)
 		}
-		ee.WriteMapEnd()
 	} else {
-		ee.WriteArrayStart(newlen)
-		if elemsep {
-			for j := 0; j < newlen; j++ {
-				ee.WriteArrayElem()
-				e.encodeValue(fkvs[j].r, nil, true)
-			}
-		} else {
-			for j := 0; j < newlen; j++ {
-				e.encodeValue(fkvs[j].r, nil, true)
+		ee.EncodeArrayStart(newlen)
+		for j := 0; j < newlen; j++ {
+			kv = fkvs[j]
+			if cr != nil {
+				cr.sendContainerState(containerArrayElem)
 			}
+			e.encodeValue(kv.r, nil)
+		}
+		if cr != nil {
+			cr.sendContainerState(containerArrayEnd)
 		}
-		ee.WriteArrayEnd()
 	}
 
 	// do not use defer. Instead, use explicit pool return at end of function.
 	// defer has a cost we are trying to avoid.
 	// If there is a panic and these slices are not returned, it is ok.
-	if spool != nil {
-		spool.Put(poolv)
+	if pool != nil {
+		pool.Put(poolv)
 	}
 }
 
-func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
-	ee := e.e
+// func (f *encFnInfo) kPtr(rv reflect.Value) {
+// 	debugf(">>>>>>> ??? encode kPtr called - shouldn't get called")
+// 	if rv.IsNil() {
+// 		f.e.e.encodeNil()
+// 		return
+// 	}
+// 	f.e.encodeValue(rv.Elem())
+// }
+
+// func (f *encFnInfo) kInterface(rv reflect.Value) {
+// 	println("kInterface called")
+// 	debug.PrintStack()
+// 	if rv.IsNil() {
+// 		f.e.e.EncodeNil()
+// 		return
+// 	}
+// 	f.e.encodeValue(rv.Elem(), nil)
+// }
+
+func (f *encFnInfo) kMap(rv reflect.Value) {
+	ee := f.e.e
 	if rv.IsNil() {
 		ee.EncodeNil()
 		return
 	}
 
 	l := rv.Len()
-	ee.WriteMapStart(l)
-	elemsep := e.esep
+	ee.EncodeMapStart(l)
+	e := f.e
+	cr := e.cr
 	if l == 0 {
-		ee.WriteMapEnd()
+		if cr != nil {
+			cr.sendContainerState(containerMapEnd)
+		}
 		return
 	}
-	// var asSymbols bool
+	var asSymbols bool
 	// determine the underlying key and val encFn's for the map.
 	// This eliminates some work which is done for each loop iteration i.e.
 	// rv.Type(), ref.ValueOf(rt).Pointer(), then check map/list for fn.
@@ -677,295 +676,269 @@ func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
 	// However, if kind is reflect.Interface, do not pre-determine the
 	// encoding type, because preEncodeValue may break it down to
 	// a concrete type and kInterface will bomb.
-	var keyFn, valFn *codecFn
+	var keyFn, valFn *encFn
 	ti := f.ti
-	rtkey0 := ti.key
-	rtkey := rtkey0
-	rtval0 := ti.elem
-	rtval := rtval0
-	// rtkeyid := rt2id(rtkey0)
+	rtkey := ti.rt.Key()
+	rtval := ti.rt.Elem()
+	rtkeyid := reflect.ValueOf(rtkey).Pointer()
+	// keyTypeIsString := f.ti.rt.Key().Kind() == reflect.String
+	var keyTypeIsString = rtkeyid == stringTypId
+	if keyTypeIsString {
+		asSymbols = e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
+	} else {
+		for rtkey.Kind() == reflect.Ptr {
+			rtkey = rtkey.Elem()
+		}
+		if rtkey.Kind() != reflect.Interface {
+			rtkeyid = reflect.ValueOf(rtkey).Pointer()
+			keyFn = e.getEncFn(rtkeyid, rtkey, true, true)
+		}
+	}
 	for rtval.Kind() == reflect.Ptr {
 		rtval = rtval.Elem()
 	}
 	if rtval.Kind() != reflect.Interface {
-		valFn = e.cfer().get(rtval, true, true)
+		rtvalid := reflect.ValueOf(rtval).Pointer()
+		valFn = e.getEncFn(rtvalid, rtval, true, true)
 	}
 	mks := rv.MapKeys()
+	// for j, lmks := 0, len(mks); j < lmks; j++ {
 
 	if e.h.Canonical {
-		e.kMapCanonical(rtkey, rv, mks, valFn)
-		ee.WriteMapEnd()
-		return
-	}
-
-	var keyTypeIsString = stringTypId == rt2id(rtkey0) // rtkeyid
-	if !keyTypeIsString {
-		for rtkey.Kind() == reflect.Ptr {
-			rtkey = rtkey.Elem()
-		}
-		if rtkey.Kind() != reflect.Interface {
-			// rtkeyid = rt2id(rtkey)
-			keyFn = e.cfer().get(rtkey, true, true)
+		e.kMapCanonical(rtkeyid, rtkey, rv, mks, valFn, asSymbols)
+	} else {
+		for j := range mks {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			if keyTypeIsString {
+				if asSymbols {
+					ee.EncodeSymbol(mks[j].String())
+				} else {
+					ee.EncodeString(c_UTF8, mks[j].String())
+				}
+			} else {
+				e.encodeValue(mks[j], keyFn)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encodeValue(rv.MapIndex(mks[j]), valFn)
 		}
 	}
-
-	// for j, lmks := 0, len(mks); j < lmks; j++ {
-	for j := range mks {
-		if elemsep {
-			ee.WriteMapElemKey()
-		}
-		if keyTypeIsString {
-			ee.EncodeString(cUTF8, mks[j].String())
-		} else {
-			e.encodeValue(mks[j], keyFn, true)
-		}
-		if elemsep {
-			ee.WriteMapElemValue()
-		}
-		e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
-
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) kMapCanonical(rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *codecFn) {
+func (e *Encoder) kMapCanonical(rtkeyid uintptr, rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *encFn, asSymbols bool) {
 	ee := e.e
-	elemsep := e.esep
+	cr := e.cr
 	// we previously did out-of-band if an extension was registered.
 	// This is not necessary, as the natural kind is sufficient for ordering.
 
-	switch rtkey.Kind() {
-	case reflect.Bool:
-		mksv := make([]boolRv, len(mks))
+	if rtkeyid == uint8SliceTypId {
+		mksv := make([]bytesRv, len(mks))
 		for i, k := range mks {
 			v := &mksv[i]
 			v.r = k
-			v.v = k.Bool()
+			v.v = k.Bytes()
 		}
-		sort.Sort(boolRvSlice(mksv))
+		sort.Sort(bytesRvSlice(mksv))
 		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-			ee.EncodeBool(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
+			ee.EncodeStringBytes(c_RAW, mksv[i].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.String:
-		mksv := make([]stringRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.String()
+			e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
 		}
-		sort.Sort(stringRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
+	} else {
+		switch rtkey.Kind() {
+		case reflect.Bool:
+			mksv := make([]boolRv, len(mks))
+			for i, k := range mks {
+				v := &mksv[i]
+				v.r = k
+				v.v = k.Bool()
 			}
-			ee.EncodeString(cUTF8, mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
+			sort.Sort(boolRvSlice(mksv))
+			for i := range mksv {
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				ee.EncodeBool(mksv[i].v)
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
 			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
-		mksv := make([]uintRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Uint()
-		}
-		sort.Sort(uintRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
+		case reflect.String:
+			mksv := make([]stringRv, len(mks))
+			for i, k := range mks {
+				v := &mksv[i]
+				v.r = k
+				v.v = k.String()
 			}
-			ee.EncodeUint(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
+			sort.Sort(stringRvSlice(mksv))
+			for i := range mksv {
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				if asSymbols {
+					ee.EncodeSymbol(mksv[i].v)
+				} else {
+					ee.EncodeString(c_UTF8, mksv[i].v)
+				}
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
 			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
-		mksv := make([]intRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Int()
-		}
-		sort.Sort(intRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
+		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
+			mksv := make([]uintRv, len(mks))
+			for i, k := range mks {
+				v := &mksv[i]
+				v.r = k
+				v.v = k.Uint()
 			}
-			ee.EncodeInt(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
+			sort.Sort(uintRvSlice(mksv))
+			for i := range mksv {
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				ee.EncodeUint(mksv[i].v)
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
 			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Float32:
-		mksv := make([]floatRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Float()
-		}
-		sort.Sort(floatRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
+		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+			mksv := make([]intRv, len(mks))
+			for i, k := range mks {
+				v := &mksv[i]
+				v.r = k
+				v.v = k.Int()
 			}
-			ee.EncodeFloat32(float32(mksv[i].v))
-			if elemsep {
-				ee.WriteMapElemValue()
+			sort.Sort(intRvSlice(mksv))
+			for i := range mksv {
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				ee.EncodeInt(mksv[i].v)
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
 			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Float64:
-		mksv := make([]floatRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Float()
-		}
-		sort.Sort(floatRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
+		case reflect.Float32:
+			mksv := make([]floatRv, len(mks))
+			for i, k := range mks {
+				v := &mksv[i]
+				v.r = k
+				v.v = k.Float()
 			}
-			ee.EncodeFloat64(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
+			sort.Sort(floatRvSlice(mksv))
+			for i := range mksv {
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				ee.EncodeFloat32(float32(mksv[i].v))
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
 			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Struct:
-		if rv.Type() == timeTyp {
-			mksv := make([]timeRv, len(mks))
+		case reflect.Float64:
+			mksv := make([]floatRv, len(mks))
 			for i, k := range mks {
 				v := &mksv[i]
 				v.r = k
-				v.v = rv2i(k).(time.Time)
+				v.v = k.Float()
 			}
-			sort.Sort(timeRvSlice(mksv))
+			sort.Sort(floatRvSlice(mksv))
 			for i := range mksv {
-				if elemsep {
-					ee.WriteMapElemKey()
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
 				}
-				ee.EncodeTime(mksv[i].v)
-				if elemsep {
-					ee.WriteMapElemValue()
+				ee.EncodeFloat64(mksv[i].v)
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
 				}
-				e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+				e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
 			}
-			break
-		}
-		fallthrough
-	default:
-		// out-of-band
-		// first encode each key to a []byte first, then sort them, then record
-		var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		mksbv := make([]bytesRv, len(mks))
-		for i, k := range mks {
-			v := &mksbv[i]
-			l := len(mksv)
-			e2.MustEncode(k)
-			v.r = k
-			v.v = mksv[l:]
-		}
-		sort.Sort(bytesRvSlice(mksbv))
-		for j := range mksbv {
-			if elemsep {
-				ee.WriteMapElemKey()
+		default:
+			// out-of-band
+			// first encode each key to a []byte first, then sort them, then record
+			var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
+			e2 := NewEncoderBytes(&mksv, e.hh)
+			mksbv := make([]bytesRv, len(mks))
+			for i, k := range mks {
+				v := &mksbv[i]
+				l := len(mksv)
+				e2.MustEncode(k)
+				v.r = k
+				v.v = mksv[l:]
+				// fmt.Printf(">>>>> %s\n", mksv[l:])
 			}
-			e.asis(mksbv[j].v)
-			if elemsep {
-				ee.WriteMapElemValue()
+			sort.Sort(bytesRvSlice(mksbv))
+			for j := range mksbv {
+				if cr != nil {
+					cr.sendContainerState(containerMapKey)
+				}
+				e.asis(mksbv[j].v)
+				if cr != nil {
+					cr.sendContainerState(containerMapValue)
+				}
+				e.encodeValue(rv.MapIndex(mksbv[j].r), valFn)
 			}
-			e.encodeValue(rv.MapIndex(mksbv[j].r), valFn, true)
 		}
 	}
 }
 
-// // --------------------------------------------------
+// --------------------------------------------------
 
-type encWriterSwitch struct {
-	wi *ioEncWriter
-	// wb bytesEncWriter
-	wb   bytesEncAppender
-	wx   bool // if bytes, wx=true
-	esep bool // whether it has elem separators
-	isas bool // whether e.as != nil
+// encFn encapsulates the captured variables and the encode function.
+// This way, we only do some calculations one times, and pass to the
+// code block that should be called (encapsulated in a function)
+// instead of executing the checks every time.
+type encFn struct {
+	i encFnInfo
+	f func(*encFnInfo, reflect.Value)
 }
 
-// // TODO: Uncomment after mid-stack inlining enabled in go 1.11
+// --------------------------------------------------
 
-// func (z *encWriterSwitch) writeb(s []byte) {
-// 	if z.wx {
-// 		z.wb.writeb(s)
-// 	} else {
-// 		z.wi.writeb(s)
-// 	}
-// }
-// func (z *encWriterSwitch) writestr(s string) {
-// 	if z.wx {
-// 		z.wb.writestr(s)
-// 	} else {
-// 		z.wi.writestr(s)
-// 	}
-// }
-// func (z *encWriterSwitch) writen1(b1 byte) {
-// 	if z.wx {
-// 		z.wb.writen1(b1)
-// 	} else {
-// 		z.wi.writen1(b1)
-// 	}
-// }
-// func (z *encWriterSwitch) writen2(b1, b2 byte) {
-// 	if z.wx {
-// 		z.wb.writen2(b1, b2)
-// 	} else {
-// 		z.wi.writen2(b1, b2)
-// 	}
-// }
+type encRtidFn struct {
+	rtid uintptr
+	fn   encFn
+}
 
 // An Encoder writes an object to an output stream in the codec format.
 type Encoder struct {
-	panicHdl
 	// hopefully, reduce derefencing cost by laying the encWriter inside the Encoder
 	e encDriver
 	// NOTE: Encoder shouldn't call it's write methods,
 	// as the handler MAY need to do some coordination.
-	w encWriter
-
-	h  *BasicHandle
-	bw *bufio.Writer
-	as encDriverAsis
-
-	// ---- cpu cache line boundary?
+	w  encWriter
+	s  []encRtidFn
+	ci set
+	be bool // is binary encoding
+	js bool // is json handle
 
-	// ---- cpu cache line boundary?
-	encWriterSwitch
-	err error
+	wi ioEncWriter
+	wb bytesEncWriter
 
-	// ---- cpu cache line boundary?
-	codecFnPooler
-	ci set
-	js bool    // here, so that no need to piggy back on *codecFner for this
-	be bool    // here, so that no need to piggy back on *codecFner for this
-	_  [6]byte // padding
+	h  *BasicHandle
+	hh Handle
 
-	// ---- writable fields during execution --- *try* to keep in sep cache line
+	cr containerStateRecv
+	as encDriverAsis
 
-	// ---- cpu cache line boundary?
-	// b [scratchByteArrayLen]byte
-	// _ [cacheLineSize - scratchByteArrayLen]byte // padding
-	b [cacheLineSize - 0]byte // used for encoding a chan or (non-addressable) array of bytes
+	f map[uintptr]*encFn
+	b [scratchByteArrayLen]byte
 }
 
 // NewEncoder returns an Encoder for encoding into an io.Writer.
@@ -990,95 +963,59 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
 }
 
 func newEncoder(h Handle) *Encoder {
-	e := &Encoder{h: h.getBasicHandle(), err: errEncoderNotInitialized}
-	e.hh = h
-	e.esep = h.hasElemSeparators()
+	e := &Encoder{hh: h, h: h.getBasicHandle(), be: h.isBinary()}
+	_, e.js = h.(*JsonHandle)
+	e.e = h.newEncDriver(e)
+	e.as, _ = e.e.(encDriverAsis)
+	e.cr, _ = e.e.(containerStateRecv)
 	return e
 }
 
-func (e *Encoder) resetCommon() {
-	if e.e == nil || e.hh.recreateEncDriver(e.e) {
-		e.e = e.hh.newEncDriver(e)
-		e.as, e.isas = e.e.(encDriverAsis)
-		// e.cr, _ = e.e.(containerStateRecv)
-	}
-	e.be = e.hh.isBinary()
-	_, e.js = e.hh.(*JsonHandle)
-	e.e.reset()
-	e.err = nil
-}
-
-// Reset resets the Encoder with a new output stream.
+// Reset the Encoder with a new output stream.
 //
 // This accommodates using the state of the Encoder,
 // where it has "cached" information about sub-engines.
 func (e *Encoder) Reset(w io.Writer) {
-	if w == nil {
-		return
-	}
-	if e.wi == nil {
-		e.wi = new(ioEncWriter)
-	}
-	var ok bool
-	e.wx = false
-	e.wi.w = w
-	if e.h.WriterBufferSize > 0 {
-		e.bw = bufio.NewWriterSize(w, e.h.WriterBufferSize)
-		e.wi.bw = e.bw
-		e.wi.sw = e.bw
-		e.wi.fw = e.bw
-		e.wi.ww = e.bw
+	ww, ok := w.(ioEncWriterWriter)
+	if ok {
+		e.wi.w = ww
 	} else {
-		if e.wi.bw, ok = w.(io.ByteWriter); !ok {
-			e.wi.bw = e.wi
-		}
-		if e.wi.sw, ok = w.(ioEncStringWriter); !ok {
-			e.wi.sw = e.wi
-		}
-		e.wi.fw, _ = w.(ioFlusher)
-		e.wi.ww = w
+		sww := &e.wi.s
+		sww.w = w
+		sww.bw, _ = w.(io.ByteWriter)
+		sww.sw, _ = w.(ioEncStringWriter)
+		e.wi.w = sww
+		//ww = bufio.NewWriterSize(w, defEncByteBufSize)
 	}
-	e.w = e.wi
-	e.resetCommon()
+	e.w = &e.wi
+	e.e.reset()
 }
 
-// ResetBytes resets the Encoder with a new destination output []byte.
 func (e *Encoder) ResetBytes(out *[]byte) {
-	if out == nil {
-		return
-	}
-	var in []byte
-	if out != nil {
-		in = *out
-	}
+	in := *out
 	if in == nil {
 		in = make([]byte, defEncByteBufSize)
 	}
-	e.wx = true
-	e.wb.reset(in, out)
+	e.wb.b, e.wb.out, e.wb.c = in, out, 0
 	e.w = &e.wb
-	e.resetCommon()
+	e.e.reset()
 }
 
+// func (e *Encoder) sendContainerState(c containerState) {
+// 	if e.cr != nil {
+// 		e.cr.sendContainerState(c)
+// 	}
+// }
+
 // Encode writes an object into a stream.
 //
 // Encoding can be configured via the struct tag for the fields.
-// The key (in the struct tags) that we look at is configurable.
-//
-// By default, we look up the "codec" key in the struct field's tags,
-// and fall bak to the "json" key if "codec" is absent.
-// That key in struct field's tag value is the key name,
+// The "codec" key in struct field's tag value is the key name,
 // followed by an optional comma and options.
+// Note that the "json" key is used in the absence of the "codec" key.
 //
 // To set an option on all fields (e.g. omitempty on all fields), you
-// can create a field called _struct, and set flags on it. The options
-// which can be set on _struct are:
-//    - omitempty: so all fields are omitted if empty
-//    - toarray: so struct is encoded as an array
-//    - int: so struct key names are encoded as signed integers (instead of strings)
-//    - uint: so struct key names are encoded as unsigned integers (instead of strings)
-//    - float: so struct key names are encoded as floats (instead of strings)
-// More details on these below.
+// can create a field called _struct, and set flags on it.
 //
 // Struct values "usually" encode as maps. Each exported struct field is encoded unless:
 //    - the field's tag is "-", OR
@@ -1086,19 +1023,10 @@ func (e *Encoder) ResetBytes(out *[]byte) {
 //
 // When encoding as a map, the first string in the tag (before the comma)
 // is the map key string to use when encoding.
-// ...
-// This key is typically encoded as a string.
-// However, there are instances where the encoded stream has mapping keys encoded as numbers.
-// For example, some cbor streams have keys as integer codes in the stream, but they should map
-// to fields in a structured object. Consequently, a struct is the natural representation in code.
-// For these, configure the struct to encode/decode the keys as numbers (instead of string).
-// This is done with the int,uint or float option on the _struct field (see above).
 //
 // However, struct values may encode as arrays. This happens when:
 //    - StructToArray Encode option is set, OR
 //    - the tag on the _struct field sets the "toarray" option
-// Note that omitempty is ignored when encoding struct values as arrays,
-// as an entry must be encoded for each field, to maintain its position.
 //
 // Values with types that implement MapBySlice are encoded as stream maps.
 //
@@ -1125,77 +1053,51 @@ func (e *Encoder) ResetBytes(out *[]byte) {
 //      }
 //
 //      type MyStruct struct {
-//          _struct bool    `codec:",toarray"`     //encode struct as an array
-//      }
-//
-//      type MyStruct struct {
-//          _struct bool    `codec:",uint"`        //encode struct with "unsigned integer" keys
-//          Field1 string   `codec:"1"`            //encode Field1 key using: EncodeInt(1)
-//          Field2 string   `codec:"2"`            //encode Field2 key using: EncodeInt(2)
+//          _struct bool    `codec:",omitempty,toarray"`   //set omitempty for every field
+//                                                         //and encode struct as an array
 //      }
 //
 // The mode of encoding is based on the type of the value. When a value is seen:
 //   - If a Selfer, call its CodecEncodeSelf method
 //   - If an extension is registered for it, call that extension function
-//   - If implements encoding.(Binary|Text|JSON)Marshaler, call Marshal(Binary|Text|JSON) method
+//   - If it implements encoding.(Binary|Text|JSON)Marshaler, call its Marshal(Binary|Text|JSON) method
 //   - Else encode it based on its reflect.Kind
 //
 // Note that struct field names and keys in map[string]XXX will be treated as symbols.
 // Some formats support symbols (e.g. binc) and will properly encode the string
 // only once in the stream, and use a tag to refer to it thereafter.
 func (e *Encoder) Encode(v interface{}) (err error) {
-	defer e.deferred(&err)
-	e.MustEncode(v)
+	defer panicToErr(&err)
+	e.encode(v)
+	e.w.atEndOfEncode()
 	return
 }
 
 // MustEncode is like Encode, but panics if unable to Encode.
 // This provides insight to the code location that triggered the error.
 func (e *Encoder) MustEncode(v interface{}) {
-	if e.err != nil {
-		panic(e.err)
-	}
 	e.encode(v)
-	e.e.atEndOfEncode()
 	e.w.atEndOfEncode()
-	e.alwaysAtEnd()
 }
 
-func (e *Encoder) deferred(err1 *error) {
-	e.alwaysAtEnd()
-	if recoverPanicToErr {
-		if x := recover(); x != nil {
-			panicValToErr(e, x, err1)
-			panicValToErr(e, x, &e.err)
-		}
-	}
-}
-
-// func (e *Encoder) alwaysAtEnd() {
-// 	e.codecFnPooler.alwaysAtEnd()
-// }
-
 func (e *Encoder) encode(iv interface{}) {
-	if iv == nil || definitelyNil(iv) {
-		e.e.EncodeNil()
-		return
-	}
-	if v, ok := iv.(Selfer); ok {
-		v.CodecEncodeSelf(e)
-		return
-	}
-
-	// a switch with only concrete types can be optimized.
-	// consequently, we deal with nil and interfaces outside.
+	// if ics, ok := iv.(Selfer); ok {
+	// 	ics.CodecEncodeSelf(e)
+	// 	return
+	// }
 
 	switch v := iv.(type) {
+	case nil:
+		e.e.EncodeNil()
+	case Selfer:
+		v.CodecEncodeSelf(e)
 	case Raw:
-		e.rawBytes(v)
+		e.raw(v)
 	case reflect.Value:
-		e.encodeValue(v, nil, true)
+		e.encodeValue(v, nil)
 
 	case string:
-		e.e.EncodeString(cUTF8, v)
+		e.e.EncodeString(c_UTF8, v)
 	case bool:
 		e.e.EncodeBool(v)
 	case int:
@@ -1218,22 +1120,16 @@ func (e *Encoder) encode(iv interface{}) {
 		e.e.EncodeUint(uint64(v))
 	case uint64:
 		e.e.EncodeUint(v)
-	case uintptr:
-		e.e.EncodeUint(uint64(v))
 	case float32:
 		e.e.EncodeFloat32(v)
 	case float64:
 		e.e.EncodeFloat64(v)
-	case time.Time:
-		e.e.EncodeTime(v)
-	case []uint8:
-		e.e.EncodeStringBytes(cRAW, v)
 
-	case *Raw:
-		e.rawBytes(*v)
+	case []uint8:
+		e.e.EncodeStringBytes(c_RAW, v)
 
 	case *string:
-		e.e.EncodeString(cUTF8, *v)
+		e.e.EncodeString(c_UTF8, *v)
 	case *bool:
 		e.e.EncodeBool(*v)
 	case *int:
@@ -1256,31 +1152,24 @@ func (e *Encoder) encode(iv interface{}) {
 		e.e.EncodeUint(uint64(*v))
 	case *uint64:
 		e.e.EncodeUint(*v)
-	case *uintptr:
-		e.e.EncodeUint(uint64(*v))
 	case *float32:
 		e.e.EncodeFloat32(*v)
 	case *float64:
 		e.e.EncodeFloat64(*v)
-	case *time.Time:
-		e.e.EncodeTime(*v)
 
 	case *[]uint8:
-		e.e.EncodeStringBytes(cRAW, *v)
+		e.e.EncodeStringBytes(c_RAW, *v)
 
 	default:
+		const checkCodecSelfer1 = true // in case T is passed, where *T is a Selfer, still checkCodecSelfer
 		if !fastpathEncodeTypeSwitch(iv, e) {
-			// checkfastpath=true (not false), as underlying slice/map type may be fast-path
-			e.encodeValue(reflect.ValueOf(iv), nil, true)
+			e.encodeI(iv, false, checkCodecSelfer1)
 		}
 	}
 }
 
-func (e *Encoder) encodeValue(rv reflect.Value, fn *codecFn, checkFastpath bool) {
-	// if a valid fn is passed, it MUST BE for the dereferenced type of rv
-	var sptr uintptr
-	var rvp reflect.Value
-	var rvpValid bool
+func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, sptr uintptr, proceed bool) {
+	// use a goto statement instead of a recursive function for ptr/interface.
 TOP:
 	switch rv.Kind() {
 	case reflect.Ptr:
@@ -1288,8 +1177,6 @@ TOP:
 			e.e.EncodeNil()
 			return
 		}
-		rvpValid = true
-		rvp = rv
 		rv = rv.Elem()
 		if e.h.CheckCircularRef && rv.Kind() == reflect.Struct {
 			// TODO: Movable pointers will be an issue here. Future problem.
@@ -1314,31 +1201,165 @@ TOP:
 		return
 	}
 
-	if sptr != 0 && (&e.ci).add(sptr) {
-		e.errorf("circular reference found: # %d", sptr)
-	}
+	proceed = true
+	rv2 = rv
+	return
+}
 
+func (e *Encoder) doEncodeValue(rv reflect.Value, fn *encFn, sptr uintptr,
+	checkFastpath, checkCodecSelfer bool) {
+	if sptr != 0 {
+		if (&e.ci).add(sptr) {
+			e.errorf("circular reference found: # %d", sptr)
+		}
+	}
 	if fn == nil {
 		rt := rv.Type()
-		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
-		fn = e.cfer().get(rt, checkFastpath, true)
+		rtid := reflect.ValueOf(rt).Pointer()
+		// fn = e.getEncFn(rtid, rt, true, true)
+		fn = e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer)
 	}
-	if fn.i.addrE {
-		if rvpValid {
-			fn.fe(e, &fn.i, rvp)
-		} else if rv.CanAddr() {
-			fn.fe(e, &fn.i, rv.Addr())
-		} else {
-			rv2 := reflect.New(rv.Type())
-			rv2.Elem().Set(rv)
-			fn.fe(e, &fn.i, rv2)
+	fn.f(&fn.i, rv)
+	if sptr != 0 {
+		(&e.ci).remove(sptr)
+	}
+}
+
+func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) {
+	if rv, sptr, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed {
+		e.doEncodeValue(rv, nil, sptr, checkFastpath, checkCodecSelfer)
+	}
+}
+
+func (e *Encoder) encodeValue(rv reflect.Value, fn *encFn) {
+	// if a valid fn is passed, it MUST BE for the dereferenced type of rv
+	if rv, sptr, proceed := e.preEncodeValue(rv); proceed {
+		e.doEncodeValue(rv, fn, sptr, true, true)
+	}
+}
+
+func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *encFn) {
+	// rtid := reflect.ValueOf(rt).Pointer()
+	var ok bool
+	if useMapForCodecCache {
+		fn, ok = e.f[rtid]
+	} else {
+		for i := range e.s {
+			v := &(e.s[i])
+			if v.rtid == rtid {
+				fn, ok = &(v.fn), true
+				break
+			}
 		}
+	}
+	if ok {
+		return
+	}
+
+	if useMapForCodecCache {
+		if e.f == nil {
+			e.f = make(map[uintptr]*encFn, initCollectionCap)
+		}
+		fn = new(encFn)
+		e.f[rtid] = fn
 	} else {
-		fn.fe(e, &fn.i, rv)
+		if e.s == nil {
+			e.s = make([]encRtidFn, 0, initCollectionCap)
+		}
+		e.s = append(e.s, encRtidFn{rtid: rtid})
+		fn = &(e.s[len(e.s)-1]).fn
 	}
-	if sptr != 0 {
-		(&e.ci).remove(sptr)
+
+	ti := e.h.getTypeInfo(rtid, rt)
+	fi := &(fn.i)
+	fi.e = e
+	fi.ti = ti
+
+	if checkCodecSelfer && ti.cs {
+		fn.f = (*encFnInfo).selferMarshal
+	} else if rtid == rawTypId {
+		fn.f = (*encFnInfo).raw
+	} else if rtid == rawExtTypId {
+		fn.f = (*encFnInfo).rawExt
+	} else if e.e.IsBuiltinType(rtid) {
+		fn.f = (*encFnInfo).builtin
+	} else if xfFn := e.h.getExt(rtid); xfFn != nil {
+		fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext
+		fn.f = (*encFnInfo).ext
+	} else if supportMarshalInterfaces && e.be && ti.bm {
+		fn.f = (*encFnInfo).binaryMarshal
+	} else if supportMarshalInterfaces && !e.be && e.js && ti.jm {
+		//If JSON, we should check JSONMarshal before textMarshal
+		fn.f = (*encFnInfo).jsonMarshal
+	} else if supportMarshalInterfaces && !e.be && ti.tm {
+		fn.f = (*encFnInfo).textMarshal
+	} else {
+		rk := rt.Kind()
+		if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
+			if rt.PkgPath() == "" { // un-named slice or map
+				if idx := fastpathAV.index(rtid); idx != -1 {
+					fn.f = fastpathAV[idx].encfn
+				}
+			} else {
+				ok = false
+				// use mapping for underlying type if there
+				var rtu reflect.Type
+				if rk == reflect.Map {
+					rtu = reflect.MapOf(rt.Key(), rt.Elem())
+				} else {
+					rtu = reflect.SliceOf(rt.Elem())
+				}
+				rtuid := reflect.ValueOf(rtu).Pointer()
+				if idx := fastpathAV.index(rtuid); idx != -1 {
+					xfnf := fastpathAV[idx].encfn
+					xrt := fastpathAV[idx].rt
+					fn.f = func(xf *encFnInfo, xrv reflect.Value) {
+						xfnf(xf, xrv.Convert(xrt))
+					}
+				}
+			}
+		}
+		if fn.f == nil {
+			switch rk {
+			case reflect.Bool:
+				fn.f = (*encFnInfo).kBool
+			case reflect.String:
+				fn.f = (*encFnInfo).kString
+			case reflect.Float64:
+				fn.f = (*encFnInfo).kFloat64
+			case reflect.Float32:
+				fn.f = (*encFnInfo).kFloat32
+			case reflect.Int, reflect.Int8, reflect.Int64, reflect.Int32, reflect.Int16:
+				fn.f = (*encFnInfo).kInt
+			case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uintptr:
+				fn.f = (*encFnInfo).kUint
+			case reflect.Invalid:
+				fn.f = (*encFnInfo).kInvalid
+			case reflect.Chan:
+				fi.seq = seqTypeChan
+				fn.f = (*encFnInfo).kSlice
+			case reflect.Slice:
+				fi.seq = seqTypeSlice
+				fn.f = (*encFnInfo).kSlice
+			case reflect.Array:
+				fi.seq = seqTypeArray
+				fn.f = (*encFnInfo).kSlice
+			case reflect.Struct:
+				fn.f = (*encFnInfo).kStruct
+				// reflect.Ptr and reflect.Interface are handled already by preEncodeValue
+				// case reflect.Ptr:
+				// 	fn.f = (*encFnInfo).kPtr
+				// case reflect.Interface:
+				// 	fn.f = (*encFnInfo).kInterface
+			case reflect.Map:
+				fn.f = (*encFnInfo).kMap
+			default:
+				fn.f = (*encFnInfo).kErr
+			}
+		}
 	}
+
+	return
 }
 
 func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) {
@@ -1355,21 +1376,86 @@ func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) {
 }
 
 func (e *Encoder) asis(v []byte) {
-	if e.isas {
-		e.as.EncodeAsis(v)
-	} else {
+	if e.as == nil {
 		e.w.writeb(v)
+	} else {
+		e.as.EncodeAsis(v)
 	}
 }
 
-func (e *Encoder) rawBytes(vv Raw) {
+func (e *Encoder) raw(vv Raw) {
 	v := []byte(vv)
 	if !e.h.Raw {
 		e.errorf("Raw values cannot be encoded: %v", v)
 	}
-	e.asis(v)
+	if e.as == nil {
+		e.w.writeb(v)
+	} else {
+		e.as.EncodeAsis(v)
+	}
+}
+
+func (e *Encoder) errorf(format string, params ...interface{}) {
+	err := fmt.Errorf(format, params...)
+	panic(err)
 }
 
-func (e *Encoder) wrapErrstr(v interface{}, err *error) {
-	*err = fmt.Errorf("%s encode error: %v", e.hh.Name(), v)
+// ----------------------------------------
+
+const encStructPoolLen = 5
+
+// encStructPool is an array of sync.Pool.
+// Each element of the array pools one of encStructPool(8|16|32|64).
+// It allows the re-use of slices up to 64 in length.
+// A performance cost of encoding structs was collecting
+// which values were empty and should be omitted.
+// We needed slices of reflect.Value and string to collect them.
+// This shared pool reduces the amount of unnecessary creation we do.
+// The cost is that of locking sometimes, but sync.Pool is efficient
+// enough to reduce thread contention.
+var encStructPool [encStructPoolLen]sync.Pool
+
+func init() {
+	encStructPool[0].New = func() interface{} { return new([8]stringRv) }
+	encStructPool[1].New = func() interface{} { return new([16]stringRv) }
+	encStructPool[2].New = func() interface{} { return new([32]stringRv) }
+	encStructPool[3].New = func() interface{} { return new([64]stringRv) }
+	encStructPool[4].New = func() interface{} { return new([128]stringRv) }
 }
+
+func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []stringRv) {
+	// if encStructPoolLen != 5 { // constant chec, so removed at build time.
+	// 	panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed
+	// }
+	// idxpool := newlen / 8
+	if newlen <= 8 {
+		p = &encStructPool[0]
+		v = p.Get()
+		s = v.(*[8]stringRv)[:newlen]
+	} else if newlen <= 16 {
+		p = &encStructPool[1]
+		v = p.Get()
+		s = v.(*[16]stringRv)[:newlen]
+	} else if newlen <= 32 {
+		p = &encStructPool[2]
+		v = p.Get()
+		s = v.(*[32]stringRv)[:newlen]
+	} else if newlen <= 64 {
+		p = &encStructPool[3]
+		v = p.Get()
+		s = v.(*[64]stringRv)[:newlen]
+	} else if newlen <= 128 {
+		p = &encStructPool[4]
+		v = p.Get()
+		s = v.(*[128]stringRv)[:newlen]
+	} else {
+		s = make([]stringRv, newlen)
+	}
+	return
+}
+
+// ----------------------------------------
+
+// func encErr(format string, params ...interface{}) {
+// 	doPanic(msgTagEnc, format, params...)
+// }
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.generated.go b/vendor/github.com/ugorji/go/codec/fast-path.generated.go
index 87f2562f6..f2e5d2dcf 100644
--- a/vendor/github.com/ugorji/go/codec/fast-path.generated.go
+++ b/vendor/github.com/ugorji/go/codec/fast-path.generated.go
@@ -3,7 +3,10 @@
 // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
-// Code generated from fast-path.go.tmpl - DO NOT EDIT.
+// ************************************************************
+// DO NOT EDIT.
+// THIS FILE IS AUTO-GENERATED from fast-path.go.tmpl
+// ************************************************************
 
 package codec
 
@@ -15,19 +18,19 @@ package codec
 // This file can be omitted without causing a build failure.
 //
 // The advantage of fast paths is:
-//	  - Many calls bypass reflection altogether
+//    - Many calls bypass reflection altogether
 //
 // Currently support
-//	  - slice of all builtin types,
-//	  - map of all builtin types to string or interface value
-//	  - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
+//    - slice of all builtin types,
+//    - map of all builtin types to string or interface value
+//    - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
 // This should provide adequate "typical" implementations.
 //
 // Note that fast track decode functions must handle values for which an address cannot be obtained.
 // For example:
-//	 m2 := map[string]int{}
-//	 p2 := []interface{}{m2}
-//	 // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
+//   m2 := map[string]int{}
+//   p2 := []interface{}{m2}
+//   // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
 //
 
 import (
@@ -37,6 +40,9 @@ import (
 
 const fastpathEnabled = true
 
+const fastpathCheckNilFalse = false // for reflect
+const fastpathCheckNilTrue = true   // for type switch
+
 type fastpathT struct{}
 
 var fastpathTV fastpathT
@@ -44,8 +50,8 @@ var fastpathTV fastpathT
 type fastpathE struct {
 	rtid  uintptr
 	rt    reflect.Type
-	encfn func(*Encoder, *codecFnInfo, reflect.Value)
-	decfn func(*Decoder, *codecFnInfo, reflect.Value)
+	encfn func(*encFnInfo, reflect.Value)
+	decfn func(*decFnInfo, reflect.Value)
 }
 
 type fastpathA [271]fastpathE
@@ -78,288 +84,286 @@ var fastpathAV fastpathA
 // due to possible initialization loop error, make fastpath in an init()
 func init() {
 	i := 0
-	fn := func(v interface{},
-		fe func(*Encoder, *codecFnInfo, reflect.Value),
-		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
+	fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) {
 		xrt := reflect.TypeOf(v)
-		xptr := rt2id(xrt)
+		xptr := reflect.ValueOf(xrt).Pointer()
 		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
 		i++
 		return
 	}
 
-	fn([]interface{}(nil), (*Encoder).fastpathEncSliceIntfR, (*Decoder).fastpathDecSliceIntfR)
-	fn([]string(nil), (*Encoder).fastpathEncSliceStringR, (*Decoder).fastpathDecSliceStringR)
-	fn([]float32(nil), (*Encoder).fastpathEncSliceFloat32R, (*Decoder).fastpathDecSliceFloat32R)
-	fn([]float64(nil), (*Encoder).fastpathEncSliceFloat64R, (*Decoder).fastpathDecSliceFloat64R)
-	fn([]uint(nil), (*Encoder).fastpathEncSliceUintR, (*Decoder).fastpathDecSliceUintR)
-	fn([]uint16(nil), (*Encoder).fastpathEncSliceUint16R, (*Decoder).fastpathDecSliceUint16R)
-	fn([]uint32(nil), (*Encoder).fastpathEncSliceUint32R, (*Decoder).fastpathDecSliceUint32R)
-	fn([]uint64(nil), (*Encoder).fastpathEncSliceUint64R, (*Decoder).fastpathDecSliceUint64R)
-	fn([]uintptr(nil), (*Encoder).fastpathEncSliceUintptrR, (*Decoder).fastpathDecSliceUintptrR)
-	fn([]int(nil), (*Encoder).fastpathEncSliceIntR, (*Decoder).fastpathDecSliceIntR)
-	fn([]int8(nil), (*Encoder).fastpathEncSliceInt8R, (*Decoder).fastpathDecSliceInt8R)
-	fn([]int16(nil), (*Encoder).fastpathEncSliceInt16R, (*Decoder).fastpathDecSliceInt16R)
-	fn([]int32(nil), (*Encoder).fastpathEncSliceInt32R, (*Decoder).fastpathDecSliceInt32R)
-	fn([]int64(nil), (*Encoder).fastpathEncSliceInt64R, (*Decoder).fastpathDecSliceInt64R)
-	fn([]bool(nil), (*Encoder).fastpathEncSliceBoolR, (*Decoder).fastpathDecSliceBoolR)
-
-	fn(map[interface{}]interface{}(nil), (*Encoder).fastpathEncMapIntfIntfR, (*Decoder).fastpathDecMapIntfIntfR)
-	fn(map[interface{}]string(nil), (*Encoder).fastpathEncMapIntfStringR, (*Decoder).fastpathDecMapIntfStringR)
-	fn(map[interface{}]uint(nil), (*Encoder).fastpathEncMapIntfUintR, (*Decoder).fastpathDecMapIntfUintR)
-	fn(map[interface{}]uint8(nil), (*Encoder).fastpathEncMapIntfUint8R, (*Decoder).fastpathDecMapIntfUint8R)
-	fn(map[interface{}]uint16(nil), (*Encoder).fastpathEncMapIntfUint16R, (*Decoder).fastpathDecMapIntfUint16R)
-	fn(map[interface{}]uint32(nil), (*Encoder).fastpathEncMapIntfUint32R, (*Decoder).fastpathDecMapIntfUint32R)
-	fn(map[interface{}]uint64(nil), (*Encoder).fastpathEncMapIntfUint64R, (*Decoder).fastpathDecMapIntfUint64R)
-	fn(map[interface{}]uintptr(nil), (*Encoder).fastpathEncMapIntfUintptrR, (*Decoder).fastpathDecMapIntfUintptrR)
-	fn(map[interface{}]int(nil), (*Encoder).fastpathEncMapIntfIntR, (*Decoder).fastpathDecMapIntfIntR)
-	fn(map[interface{}]int8(nil), (*Encoder).fastpathEncMapIntfInt8R, (*Decoder).fastpathDecMapIntfInt8R)
-	fn(map[interface{}]int16(nil), (*Encoder).fastpathEncMapIntfInt16R, (*Decoder).fastpathDecMapIntfInt16R)
-	fn(map[interface{}]int32(nil), (*Encoder).fastpathEncMapIntfInt32R, (*Decoder).fastpathDecMapIntfInt32R)
-	fn(map[interface{}]int64(nil), (*Encoder).fastpathEncMapIntfInt64R, (*Decoder).fastpathDecMapIntfInt64R)
-	fn(map[interface{}]float32(nil), (*Encoder).fastpathEncMapIntfFloat32R, (*Decoder).fastpathDecMapIntfFloat32R)
-	fn(map[interface{}]float64(nil), (*Encoder).fastpathEncMapIntfFloat64R, (*Decoder).fastpathDecMapIntfFloat64R)
-	fn(map[interface{}]bool(nil), (*Encoder).fastpathEncMapIntfBoolR, (*Decoder).fastpathDecMapIntfBoolR)
-	fn(map[string]interface{}(nil), (*Encoder).fastpathEncMapStringIntfR, (*Decoder).fastpathDecMapStringIntfR)
-	fn(map[string]string(nil), (*Encoder).fastpathEncMapStringStringR, (*Decoder).fastpathDecMapStringStringR)
-	fn(map[string]uint(nil), (*Encoder).fastpathEncMapStringUintR, (*Decoder).fastpathDecMapStringUintR)
-	fn(map[string]uint8(nil), (*Encoder).fastpathEncMapStringUint8R, (*Decoder).fastpathDecMapStringUint8R)
-	fn(map[string]uint16(nil), (*Encoder).fastpathEncMapStringUint16R, (*Decoder).fastpathDecMapStringUint16R)
-	fn(map[string]uint32(nil), (*Encoder).fastpathEncMapStringUint32R, (*Decoder).fastpathDecMapStringUint32R)
-	fn(map[string]uint64(nil), (*Encoder).fastpathEncMapStringUint64R, (*Decoder).fastpathDecMapStringUint64R)
-	fn(map[string]uintptr(nil), (*Encoder).fastpathEncMapStringUintptrR, (*Decoder).fastpathDecMapStringUintptrR)
-	fn(map[string]int(nil), (*Encoder).fastpathEncMapStringIntR, (*Decoder).fastpathDecMapStringIntR)
-	fn(map[string]int8(nil), (*Encoder).fastpathEncMapStringInt8R, (*Decoder).fastpathDecMapStringInt8R)
-	fn(map[string]int16(nil), (*Encoder).fastpathEncMapStringInt16R, (*Decoder).fastpathDecMapStringInt16R)
-	fn(map[string]int32(nil), (*Encoder).fastpathEncMapStringInt32R, (*Decoder).fastpathDecMapStringInt32R)
-	fn(map[string]int64(nil), (*Encoder).fastpathEncMapStringInt64R, (*Decoder).fastpathDecMapStringInt64R)
-	fn(map[string]float32(nil), (*Encoder).fastpathEncMapStringFloat32R, (*Decoder).fastpathDecMapStringFloat32R)
-	fn(map[string]float64(nil), (*Encoder).fastpathEncMapStringFloat64R, (*Decoder).fastpathDecMapStringFloat64R)
-	fn(map[string]bool(nil), (*Encoder).fastpathEncMapStringBoolR, (*Decoder).fastpathDecMapStringBoolR)
-	fn(map[float32]interface{}(nil), (*Encoder).fastpathEncMapFloat32IntfR, (*Decoder).fastpathDecMapFloat32IntfR)
-	fn(map[float32]string(nil), (*Encoder).fastpathEncMapFloat32StringR, (*Decoder).fastpathDecMapFloat32StringR)
-	fn(map[float32]uint(nil), (*Encoder).fastpathEncMapFloat32UintR, (*Decoder).fastpathDecMapFloat32UintR)
-	fn(map[float32]uint8(nil), (*Encoder).fastpathEncMapFloat32Uint8R, (*Decoder).fastpathDecMapFloat32Uint8R)
-	fn(map[float32]uint16(nil), (*Encoder).fastpathEncMapFloat32Uint16R, (*Decoder).fastpathDecMapFloat32Uint16R)
-	fn(map[float32]uint32(nil), (*Encoder).fastpathEncMapFloat32Uint32R, (*Decoder).fastpathDecMapFloat32Uint32R)
-	fn(map[float32]uint64(nil), (*Encoder).fastpathEncMapFloat32Uint64R, (*Decoder).fastpathDecMapFloat32Uint64R)
-	fn(map[float32]uintptr(nil), (*Encoder).fastpathEncMapFloat32UintptrR, (*Decoder).fastpathDecMapFloat32UintptrR)
-	fn(map[float32]int(nil), (*Encoder).fastpathEncMapFloat32IntR, (*Decoder).fastpathDecMapFloat32IntR)
-	fn(map[float32]int8(nil), (*Encoder).fastpathEncMapFloat32Int8R, (*Decoder).fastpathDecMapFloat32Int8R)
-	fn(map[float32]int16(nil), (*Encoder).fastpathEncMapFloat32Int16R, (*Decoder).fastpathDecMapFloat32Int16R)
-	fn(map[float32]int32(nil), (*Encoder).fastpathEncMapFloat32Int32R, (*Decoder).fastpathDecMapFloat32Int32R)
-	fn(map[float32]int64(nil), (*Encoder).fastpathEncMapFloat32Int64R, (*Decoder).fastpathDecMapFloat32Int64R)
-	fn(map[float32]float32(nil), (*Encoder).fastpathEncMapFloat32Float32R, (*Decoder).fastpathDecMapFloat32Float32R)
-	fn(map[float32]float64(nil), (*Encoder).fastpathEncMapFloat32Float64R, (*Decoder).fastpathDecMapFloat32Float64R)
-	fn(map[float32]bool(nil), (*Encoder).fastpathEncMapFloat32BoolR, (*Decoder).fastpathDecMapFloat32BoolR)
-	fn(map[float64]interface{}(nil), (*Encoder).fastpathEncMapFloat64IntfR, (*Decoder).fastpathDecMapFloat64IntfR)
-	fn(map[float64]string(nil), (*Encoder).fastpathEncMapFloat64StringR, (*Decoder).fastpathDecMapFloat64StringR)
-	fn(map[float64]uint(nil), (*Encoder).fastpathEncMapFloat64UintR, (*Decoder).fastpathDecMapFloat64UintR)
-	fn(map[float64]uint8(nil), (*Encoder).fastpathEncMapFloat64Uint8R, (*Decoder).fastpathDecMapFloat64Uint8R)
-	fn(map[float64]uint16(nil), (*Encoder).fastpathEncMapFloat64Uint16R, (*Decoder).fastpathDecMapFloat64Uint16R)
-	fn(map[float64]uint32(nil), (*Encoder).fastpathEncMapFloat64Uint32R, (*Decoder).fastpathDecMapFloat64Uint32R)
-	fn(map[float64]uint64(nil), (*Encoder).fastpathEncMapFloat64Uint64R, (*Decoder).fastpathDecMapFloat64Uint64R)
-	fn(map[float64]uintptr(nil), (*Encoder).fastpathEncMapFloat64UintptrR, (*Decoder).fastpathDecMapFloat64UintptrR)
-	fn(map[float64]int(nil), (*Encoder).fastpathEncMapFloat64IntR, (*Decoder).fastpathDecMapFloat64IntR)
-	fn(map[float64]int8(nil), (*Encoder).fastpathEncMapFloat64Int8R, (*Decoder).fastpathDecMapFloat64Int8R)
-	fn(map[float64]int16(nil), (*Encoder).fastpathEncMapFloat64Int16R, (*Decoder).fastpathDecMapFloat64Int16R)
-	fn(map[float64]int32(nil), (*Encoder).fastpathEncMapFloat64Int32R, (*Decoder).fastpathDecMapFloat64Int32R)
-	fn(map[float64]int64(nil), (*Encoder).fastpathEncMapFloat64Int64R, (*Decoder).fastpathDecMapFloat64Int64R)
-	fn(map[float64]float32(nil), (*Encoder).fastpathEncMapFloat64Float32R, (*Decoder).fastpathDecMapFloat64Float32R)
-	fn(map[float64]float64(nil), (*Encoder).fastpathEncMapFloat64Float64R, (*Decoder).fastpathDecMapFloat64Float64R)
-	fn(map[float64]bool(nil), (*Encoder).fastpathEncMapFloat64BoolR, (*Decoder).fastpathDecMapFloat64BoolR)
-	fn(map[uint]interface{}(nil), (*Encoder).fastpathEncMapUintIntfR, (*Decoder).fastpathDecMapUintIntfR)
-	fn(map[uint]string(nil), (*Encoder).fastpathEncMapUintStringR, (*Decoder).fastpathDecMapUintStringR)
-	fn(map[uint]uint(nil), (*Encoder).fastpathEncMapUintUintR, (*Decoder).fastpathDecMapUintUintR)
-	fn(map[uint]uint8(nil), (*Encoder).fastpathEncMapUintUint8R, (*Decoder).fastpathDecMapUintUint8R)
-	fn(map[uint]uint16(nil), (*Encoder).fastpathEncMapUintUint16R, (*Decoder).fastpathDecMapUintUint16R)
-	fn(map[uint]uint32(nil), (*Encoder).fastpathEncMapUintUint32R, (*Decoder).fastpathDecMapUintUint32R)
-	fn(map[uint]uint64(nil), (*Encoder).fastpathEncMapUintUint64R, (*Decoder).fastpathDecMapUintUint64R)
-	fn(map[uint]uintptr(nil), (*Encoder).fastpathEncMapUintUintptrR, (*Decoder).fastpathDecMapUintUintptrR)
-	fn(map[uint]int(nil), (*Encoder).fastpathEncMapUintIntR, (*Decoder).fastpathDecMapUintIntR)
-	fn(map[uint]int8(nil), (*Encoder).fastpathEncMapUintInt8R, (*Decoder).fastpathDecMapUintInt8R)
-	fn(map[uint]int16(nil), (*Encoder).fastpathEncMapUintInt16R, (*Decoder).fastpathDecMapUintInt16R)
-	fn(map[uint]int32(nil), (*Encoder).fastpathEncMapUintInt32R, (*Decoder).fastpathDecMapUintInt32R)
-	fn(map[uint]int64(nil), (*Encoder).fastpathEncMapUintInt64R, (*Decoder).fastpathDecMapUintInt64R)
-	fn(map[uint]float32(nil), (*Encoder).fastpathEncMapUintFloat32R, (*Decoder).fastpathDecMapUintFloat32R)
-	fn(map[uint]float64(nil), (*Encoder).fastpathEncMapUintFloat64R, (*Decoder).fastpathDecMapUintFloat64R)
-	fn(map[uint]bool(nil), (*Encoder).fastpathEncMapUintBoolR, (*Decoder).fastpathDecMapUintBoolR)
-	fn(map[uint8]interface{}(nil), (*Encoder).fastpathEncMapUint8IntfR, (*Decoder).fastpathDecMapUint8IntfR)
-	fn(map[uint8]string(nil), (*Encoder).fastpathEncMapUint8StringR, (*Decoder).fastpathDecMapUint8StringR)
-	fn(map[uint8]uint(nil), (*Encoder).fastpathEncMapUint8UintR, (*Decoder).fastpathDecMapUint8UintR)
-	fn(map[uint8]uint8(nil), (*Encoder).fastpathEncMapUint8Uint8R, (*Decoder).fastpathDecMapUint8Uint8R)
-	fn(map[uint8]uint16(nil), (*Encoder).fastpathEncMapUint8Uint16R, (*Decoder).fastpathDecMapUint8Uint16R)
-	fn(map[uint8]uint32(nil), (*Encoder).fastpathEncMapUint8Uint32R, (*Decoder).fastpathDecMapUint8Uint32R)
-	fn(map[uint8]uint64(nil), (*Encoder).fastpathEncMapUint8Uint64R, (*Decoder).fastpathDecMapUint8Uint64R)
-	fn(map[uint8]uintptr(nil), (*Encoder).fastpathEncMapUint8UintptrR, (*Decoder).fastpathDecMapUint8UintptrR)
-	fn(map[uint8]int(nil), (*Encoder).fastpathEncMapUint8IntR, (*Decoder).fastpathDecMapUint8IntR)
-	fn(map[uint8]int8(nil), (*Encoder).fastpathEncMapUint8Int8R, (*Decoder).fastpathDecMapUint8Int8R)
-	fn(map[uint8]int16(nil), (*Encoder).fastpathEncMapUint8Int16R, (*Decoder).fastpathDecMapUint8Int16R)
-	fn(map[uint8]int32(nil), (*Encoder).fastpathEncMapUint8Int32R, (*Decoder).fastpathDecMapUint8Int32R)
-	fn(map[uint8]int64(nil), (*Encoder).fastpathEncMapUint8Int64R, (*Decoder).fastpathDecMapUint8Int64R)
-	fn(map[uint8]float32(nil), (*Encoder).fastpathEncMapUint8Float32R, (*Decoder).fastpathDecMapUint8Float32R)
-	fn(map[uint8]float64(nil), (*Encoder).fastpathEncMapUint8Float64R, (*Decoder).fastpathDecMapUint8Float64R)
-	fn(map[uint8]bool(nil), (*Encoder).fastpathEncMapUint8BoolR, (*Decoder).fastpathDecMapUint8BoolR)
-	fn(map[uint16]interface{}(nil), (*Encoder).fastpathEncMapUint16IntfR, (*Decoder).fastpathDecMapUint16IntfR)
-	fn(map[uint16]string(nil), (*Encoder).fastpathEncMapUint16StringR, (*Decoder).fastpathDecMapUint16StringR)
-	fn(map[uint16]uint(nil), (*Encoder).fastpathEncMapUint16UintR, (*Decoder).fastpathDecMapUint16UintR)
-	fn(map[uint16]uint8(nil), (*Encoder).fastpathEncMapUint16Uint8R, (*Decoder).fastpathDecMapUint16Uint8R)
-	fn(map[uint16]uint16(nil), (*Encoder).fastpathEncMapUint16Uint16R, (*Decoder).fastpathDecMapUint16Uint16R)
-	fn(map[uint16]uint32(nil), (*Encoder).fastpathEncMapUint16Uint32R, (*Decoder).fastpathDecMapUint16Uint32R)
-	fn(map[uint16]uint64(nil), (*Encoder).fastpathEncMapUint16Uint64R, (*Decoder).fastpathDecMapUint16Uint64R)
-	fn(map[uint16]uintptr(nil), (*Encoder).fastpathEncMapUint16UintptrR, (*Decoder).fastpathDecMapUint16UintptrR)
-	fn(map[uint16]int(nil), (*Encoder).fastpathEncMapUint16IntR, (*Decoder).fastpathDecMapUint16IntR)
-	fn(map[uint16]int8(nil), (*Encoder).fastpathEncMapUint16Int8R, (*Decoder).fastpathDecMapUint16Int8R)
-	fn(map[uint16]int16(nil), (*Encoder).fastpathEncMapUint16Int16R, (*Decoder).fastpathDecMapUint16Int16R)
-	fn(map[uint16]int32(nil), (*Encoder).fastpathEncMapUint16Int32R, (*Decoder).fastpathDecMapUint16Int32R)
-	fn(map[uint16]int64(nil), (*Encoder).fastpathEncMapUint16Int64R, (*Decoder).fastpathDecMapUint16Int64R)
-	fn(map[uint16]float32(nil), (*Encoder).fastpathEncMapUint16Float32R, (*Decoder).fastpathDecMapUint16Float32R)
-	fn(map[uint16]float64(nil), (*Encoder).fastpathEncMapUint16Float64R, (*Decoder).fastpathDecMapUint16Float64R)
-	fn(map[uint16]bool(nil), (*Encoder).fastpathEncMapUint16BoolR, (*Decoder).fastpathDecMapUint16BoolR)
-	fn(map[uint32]interface{}(nil), (*Encoder).fastpathEncMapUint32IntfR, (*Decoder).fastpathDecMapUint32IntfR)
-	fn(map[uint32]string(nil), (*Encoder).fastpathEncMapUint32StringR, (*Decoder).fastpathDecMapUint32StringR)
-	fn(map[uint32]uint(nil), (*Encoder).fastpathEncMapUint32UintR, (*Decoder).fastpathDecMapUint32UintR)
-	fn(map[uint32]uint8(nil), (*Encoder).fastpathEncMapUint32Uint8R, (*Decoder).fastpathDecMapUint32Uint8R)
-	fn(map[uint32]uint16(nil), (*Encoder).fastpathEncMapUint32Uint16R, (*Decoder).fastpathDecMapUint32Uint16R)
-	fn(map[uint32]uint32(nil), (*Encoder).fastpathEncMapUint32Uint32R, (*Decoder).fastpathDecMapUint32Uint32R)
-	fn(map[uint32]uint64(nil), (*Encoder).fastpathEncMapUint32Uint64R, (*Decoder).fastpathDecMapUint32Uint64R)
-	fn(map[uint32]uintptr(nil), (*Encoder).fastpathEncMapUint32UintptrR, (*Decoder).fastpathDecMapUint32UintptrR)
-	fn(map[uint32]int(nil), (*Encoder).fastpathEncMapUint32IntR, (*Decoder).fastpathDecMapUint32IntR)
-	fn(map[uint32]int8(nil), (*Encoder).fastpathEncMapUint32Int8R, (*Decoder).fastpathDecMapUint32Int8R)
-	fn(map[uint32]int16(nil), (*Encoder).fastpathEncMapUint32Int16R, (*Decoder).fastpathDecMapUint32Int16R)
-	fn(map[uint32]int32(nil), (*Encoder).fastpathEncMapUint32Int32R, (*Decoder).fastpathDecMapUint32Int32R)
-	fn(map[uint32]int64(nil), (*Encoder).fastpathEncMapUint32Int64R, (*Decoder).fastpathDecMapUint32Int64R)
-	fn(map[uint32]float32(nil), (*Encoder).fastpathEncMapUint32Float32R, (*Decoder).fastpathDecMapUint32Float32R)
-	fn(map[uint32]float64(nil), (*Encoder).fastpathEncMapUint32Float64R, (*Decoder).fastpathDecMapUint32Float64R)
-	fn(map[uint32]bool(nil), (*Encoder).fastpathEncMapUint32BoolR, (*Decoder).fastpathDecMapUint32BoolR)
-	fn(map[uint64]interface{}(nil), (*Encoder).fastpathEncMapUint64IntfR, (*Decoder).fastpathDecMapUint64IntfR)
-	fn(map[uint64]string(nil), (*Encoder).fastpathEncMapUint64StringR, (*Decoder).fastpathDecMapUint64StringR)
-	fn(map[uint64]uint(nil), (*Encoder).fastpathEncMapUint64UintR, (*Decoder).fastpathDecMapUint64UintR)
-	fn(map[uint64]uint8(nil), (*Encoder).fastpathEncMapUint64Uint8R, (*Decoder).fastpathDecMapUint64Uint8R)
-	fn(map[uint64]uint16(nil), (*Encoder).fastpathEncMapUint64Uint16R, (*Decoder).fastpathDecMapUint64Uint16R)
-	fn(map[uint64]uint32(nil), (*Encoder).fastpathEncMapUint64Uint32R, (*Decoder).fastpathDecMapUint64Uint32R)
-	fn(map[uint64]uint64(nil), (*Encoder).fastpathEncMapUint64Uint64R, (*Decoder).fastpathDecMapUint64Uint64R)
-	fn(map[uint64]uintptr(nil), (*Encoder).fastpathEncMapUint64UintptrR, (*Decoder).fastpathDecMapUint64UintptrR)
-	fn(map[uint64]int(nil), (*Encoder).fastpathEncMapUint64IntR, (*Decoder).fastpathDecMapUint64IntR)
-	fn(map[uint64]int8(nil), (*Encoder).fastpathEncMapUint64Int8R, (*Decoder).fastpathDecMapUint64Int8R)
-	fn(map[uint64]int16(nil), (*Encoder).fastpathEncMapUint64Int16R, (*Decoder).fastpathDecMapUint64Int16R)
-	fn(map[uint64]int32(nil), (*Encoder).fastpathEncMapUint64Int32R, (*Decoder).fastpathDecMapUint64Int32R)
-	fn(map[uint64]int64(nil), (*Encoder).fastpathEncMapUint64Int64R, (*Decoder).fastpathDecMapUint64Int64R)
-	fn(map[uint64]float32(nil), (*Encoder).fastpathEncMapUint64Float32R, (*Decoder).fastpathDecMapUint64Float32R)
-	fn(map[uint64]float64(nil), (*Encoder).fastpathEncMapUint64Float64R, (*Decoder).fastpathDecMapUint64Float64R)
-	fn(map[uint64]bool(nil), (*Encoder).fastpathEncMapUint64BoolR, (*Decoder).fastpathDecMapUint64BoolR)
-	fn(map[uintptr]interface{}(nil), (*Encoder).fastpathEncMapUintptrIntfR, (*Decoder).fastpathDecMapUintptrIntfR)
-	fn(map[uintptr]string(nil), (*Encoder).fastpathEncMapUintptrStringR, (*Decoder).fastpathDecMapUintptrStringR)
-	fn(map[uintptr]uint(nil), (*Encoder).fastpathEncMapUintptrUintR, (*Decoder).fastpathDecMapUintptrUintR)
-	fn(map[uintptr]uint8(nil), (*Encoder).fastpathEncMapUintptrUint8R, (*Decoder).fastpathDecMapUintptrUint8R)
-	fn(map[uintptr]uint16(nil), (*Encoder).fastpathEncMapUintptrUint16R, (*Decoder).fastpathDecMapUintptrUint16R)
-	fn(map[uintptr]uint32(nil), (*Encoder).fastpathEncMapUintptrUint32R, (*Decoder).fastpathDecMapUintptrUint32R)
-	fn(map[uintptr]uint64(nil), (*Encoder).fastpathEncMapUintptrUint64R, (*Decoder).fastpathDecMapUintptrUint64R)
-	fn(map[uintptr]uintptr(nil), (*Encoder).fastpathEncMapUintptrUintptrR, (*Decoder).fastpathDecMapUintptrUintptrR)
-	fn(map[uintptr]int(nil), (*Encoder).fastpathEncMapUintptrIntR, (*Decoder).fastpathDecMapUintptrIntR)
-	fn(map[uintptr]int8(nil), (*Encoder).fastpathEncMapUintptrInt8R, (*Decoder).fastpathDecMapUintptrInt8R)
-	fn(map[uintptr]int16(nil), (*Encoder).fastpathEncMapUintptrInt16R, (*Decoder).fastpathDecMapUintptrInt16R)
-	fn(map[uintptr]int32(nil), (*Encoder).fastpathEncMapUintptrInt32R, (*Decoder).fastpathDecMapUintptrInt32R)
-	fn(map[uintptr]int64(nil), (*Encoder).fastpathEncMapUintptrInt64R, (*Decoder).fastpathDecMapUintptrInt64R)
-	fn(map[uintptr]float32(nil), (*Encoder).fastpathEncMapUintptrFloat32R, (*Decoder).fastpathDecMapUintptrFloat32R)
-	fn(map[uintptr]float64(nil), (*Encoder).fastpathEncMapUintptrFloat64R, (*Decoder).fastpathDecMapUintptrFloat64R)
-	fn(map[uintptr]bool(nil), (*Encoder).fastpathEncMapUintptrBoolR, (*Decoder).fastpathDecMapUintptrBoolR)
-	fn(map[int]interface{}(nil), (*Encoder).fastpathEncMapIntIntfR, (*Decoder).fastpathDecMapIntIntfR)
-	fn(map[int]string(nil), (*Encoder).fastpathEncMapIntStringR, (*Decoder).fastpathDecMapIntStringR)
-	fn(map[int]uint(nil), (*Encoder).fastpathEncMapIntUintR, (*Decoder).fastpathDecMapIntUintR)
-	fn(map[int]uint8(nil), (*Encoder).fastpathEncMapIntUint8R, (*Decoder).fastpathDecMapIntUint8R)
-	fn(map[int]uint16(nil), (*Encoder).fastpathEncMapIntUint16R, (*Decoder).fastpathDecMapIntUint16R)
-	fn(map[int]uint32(nil), (*Encoder).fastpathEncMapIntUint32R, (*Decoder).fastpathDecMapIntUint32R)
-	fn(map[int]uint64(nil), (*Encoder).fastpathEncMapIntUint64R, (*Decoder).fastpathDecMapIntUint64R)
-	fn(map[int]uintptr(nil), (*Encoder).fastpathEncMapIntUintptrR, (*Decoder).fastpathDecMapIntUintptrR)
-	fn(map[int]int(nil), (*Encoder).fastpathEncMapIntIntR, (*Decoder).fastpathDecMapIntIntR)
-	fn(map[int]int8(nil), (*Encoder).fastpathEncMapIntInt8R, (*Decoder).fastpathDecMapIntInt8R)
-	fn(map[int]int16(nil), (*Encoder).fastpathEncMapIntInt16R, (*Decoder).fastpathDecMapIntInt16R)
-	fn(map[int]int32(nil), (*Encoder).fastpathEncMapIntInt32R, (*Decoder).fastpathDecMapIntInt32R)
-	fn(map[int]int64(nil), (*Encoder).fastpathEncMapIntInt64R, (*Decoder).fastpathDecMapIntInt64R)
-	fn(map[int]float32(nil), (*Encoder).fastpathEncMapIntFloat32R, (*Decoder).fastpathDecMapIntFloat32R)
-	fn(map[int]float64(nil), (*Encoder).fastpathEncMapIntFloat64R, (*Decoder).fastpathDecMapIntFloat64R)
-	fn(map[int]bool(nil), (*Encoder).fastpathEncMapIntBoolR, (*Decoder).fastpathDecMapIntBoolR)
-	fn(map[int8]interface{}(nil), (*Encoder).fastpathEncMapInt8IntfR, (*Decoder).fastpathDecMapInt8IntfR)
-	fn(map[int8]string(nil), (*Encoder).fastpathEncMapInt8StringR, (*Decoder).fastpathDecMapInt8StringR)
-	fn(map[int8]uint(nil), (*Encoder).fastpathEncMapInt8UintR, (*Decoder).fastpathDecMapInt8UintR)
-	fn(map[int8]uint8(nil), (*Encoder).fastpathEncMapInt8Uint8R, (*Decoder).fastpathDecMapInt8Uint8R)
-	fn(map[int8]uint16(nil), (*Encoder).fastpathEncMapInt8Uint16R, (*Decoder).fastpathDecMapInt8Uint16R)
-	fn(map[int8]uint32(nil), (*Encoder).fastpathEncMapInt8Uint32R, (*Decoder).fastpathDecMapInt8Uint32R)
-	fn(map[int8]uint64(nil), (*Encoder).fastpathEncMapInt8Uint64R, (*Decoder).fastpathDecMapInt8Uint64R)
-	fn(map[int8]uintptr(nil), (*Encoder).fastpathEncMapInt8UintptrR, (*Decoder).fastpathDecMapInt8UintptrR)
-	fn(map[int8]int(nil), (*Encoder).fastpathEncMapInt8IntR, (*Decoder).fastpathDecMapInt8IntR)
-	fn(map[int8]int8(nil), (*Encoder).fastpathEncMapInt8Int8R, (*Decoder).fastpathDecMapInt8Int8R)
-	fn(map[int8]int16(nil), (*Encoder).fastpathEncMapInt8Int16R, (*Decoder).fastpathDecMapInt8Int16R)
-	fn(map[int8]int32(nil), (*Encoder).fastpathEncMapInt8Int32R, (*Decoder).fastpathDecMapInt8Int32R)
-	fn(map[int8]int64(nil), (*Encoder).fastpathEncMapInt8Int64R, (*Decoder).fastpathDecMapInt8Int64R)
-	fn(map[int8]float32(nil), (*Encoder).fastpathEncMapInt8Float32R, (*Decoder).fastpathDecMapInt8Float32R)
-	fn(map[int8]float64(nil), (*Encoder).fastpathEncMapInt8Float64R, (*Decoder).fastpathDecMapInt8Float64R)
-	fn(map[int8]bool(nil), (*Encoder).fastpathEncMapInt8BoolR, (*Decoder).fastpathDecMapInt8BoolR)
-	fn(map[int16]interface{}(nil), (*Encoder).fastpathEncMapInt16IntfR, (*Decoder).fastpathDecMapInt16IntfR)
-	fn(map[int16]string(nil), (*Encoder).fastpathEncMapInt16StringR, (*Decoder).fastpathDecMapInt16StringR)
-	fn(map[int16]uint(nil), (*Encoder).fastpathEncMapInt16UintR, (*Decoder).fastpathDecMapInt16UintR)
-	fn(map[int16]uint8(nil), (*Encoder).fastpathEncMapInt16Uint8R, (*Decoder).fastpathDecMapInt16Uint8R)
-	fn(map[int16]uint16(nil), (*Encoder).fastpathEncMapInt16Uint16R, (*Decoder).fastpathDecMapInt16Uint16R)
-	fn(map[int16]uint32(nil), (*Encoder).fastpathEncMapInt16Uint32R, (*Decoder).fastpathDecMapInt16Uint32R)
-	fn(map[int16]uint64(nil), (*Encoder).fastpathEncMapInt16Uint64R, (*Decoder).fastpathDecMapInt16Uint64R)
-	fn(map[int16]uintptr(nil), (*Encoder).fastpathEncMapInt16UintptrR, (*Decoder).fastpathDecMapInt16UintptrR)
-	fn(map[int16]int(nil), (*Encoder).fastpathEncMapInt16IntR, (*Decoder).fastpathDecMapInt16IntR)
-	fn(map[int16]int8(nil), (*Encoder).fastpathEncMapInt16Int8R, (*Decoder).fastpathDecMapInt16Int8R)
-	fn(map[int16]int16(nil), (*Encoder).fastpathEncMapInt16Int16R, (*Decoder).fastpathDecMapInt16Int16R)
-	fn(map[int16]int32(nil), (*Encoder).fastpathEncMapInt16Int32R, (*Decoder).fastpathDecMapInt16Int32R)
-	fn(map[int16]int64(nil), (*Encoder).fastpathEncMapInt16Int64R, (*Decoder).fastpathDecMapInt16Int64R)
-	fn(map[int16]float32(nil), (*Encoder).fastpathEncMapInt16Float32R, (*Decoder).fastpathDecMapInt16Float32R)
-	fn(map[int16]float64(nil), (*Encoder).fastpathEncMapInt16Float64R, (*Decoder).fastpathDecMapInt16Float64R)
-	fn(map[int16]bool(nil), (*Encoder).fastpathEncMapInt16BoolR, (*Decoder).fastpathDecMapInt16BoolR)
-	fn(map[int32]interface{}(nil), (*Encoder).fastpathEncMapInt32IntfR, (*Decoder).fastpathDecMapInt32IntfR)
-	fn(map[int32]string(nil), (*Encoder).fastpathEncMapInt32StringR, (*Decoder).fastpathDecMapInt32StringR)
-	fn(map[int32]uint(nil), (*Encoder).fastpathEncMapInt32UintR, (*Decoder).fastpathDecMapInt32UintR)
-	fn(map[int32]uint8(nil), (*Encoder).fastpathEncMapInt32Uint8R, (*Decoder).fastpathDecMapInt32Uint8R)
-	fn(map[int32]uint16(nil), (*Encoder).fastpathEncMapInt32Uint16R, (*Decoder).fastpathDecMapInt32Uint16R)
-	fn(map[int32]uint32(nil), (*Encoder).fastpathEncMapInt32Uint32R, (*Decoder).fastpathDecMapInt32Uint32R)
-	fn(map[int32]uint64(nil), (*Encoder).fastpathEncMapInt32Uint64R, (*Decoder).fastpathDecMapInt32Uint64R)
-	fn(map[int32]uintptr(nil), (*Encoder).fastpathEncMapInt32UintptrR, (*Decoder).fastpathDecMapInt32UintptrR)
-	fn(map[int32]int(nil), (*Encoder).fastpathEncMapInt32IntR, (*Decoder).fastpathDecMapInt32IntR)
-	fn(map[int32]int8(nil), (*Encoder).fastpathEncMapInt32Int8R, (*Decoder).fastpathDecMapInt32Int8R)
-	fn(map[int32]int16(nil), (*Encoder).fastpathEncMapInt32Int16R, (*Decoder).fastpathDecMapInt32Int16R)
-	fn(map[int32]int32(nil), (*Encoder).fastpathEncMapInt32Int32R, (*Decoder).fastpathDecMapInt32Int32R)
-	fn(map[int32]int64(nil), (*Encoder).fastpathEncMapInt32Int64R, (*Decoder).fastpathDecMapInt32Int64R)
-	fn(map[int32]float32(nil), (*Encoder).fastpathEncMapInt32Float32R, (*Decoder).fastpathDecMapInt32Float32R)
-	fn(map[int32]float64(nil), (*Encoder).fastpathEncMapInt32Float64R, (*Decoder).fastpathDecMapInt32Float64R)
-	fn(map[int32]bool(nil), (*Encoder).fastpathEncMapInt32BoolR, (*Decoder).fastpathDecMapInt32BoolR)
-	fn(map[int64]interface{}(nil), (*Encoder).fastpathEncMapInt64IntfR, (*Decoder).fastpathDecMapInt64IntfR)
-	fn(map[int64]string(nil), (*Encoder).fastpathEncMapInt64StringR, (*Decoder).fastpathDecMapInt64StringR)
-	fn(map[int64]uint(nil), (*Encoder).fastpathEncMapInt64UintR, (*Decoder).fastpathDecMapInt64UintR)
-	fn(map[int64]uint8(nil), (*Encoder).fastpathEncMapInt64Uint8R, (*Decoder).fastpathDecMapInt64Uint8R)
-	fn(map[int64]uint16(nil), (*Encoder).fastpathEncMapInt64Uint16R, (*Decoder).fastpathDecMapInt64Uint16R)
-	fn(map[int64]uint32(nil), (*Encoder).fastpathEncMapInt64Uint32R, (*Decoder).fastpathDecMapInt64Uint32R)
-	fn(map[int64]uint64(nil), (*Encoder).fastpathEncMapInt64Uint64R, (*Decoder).fastpathDecMapInt64Uint64R)
-	fn(map[int64]uintptr(nil), (*Encoder).fastpathEncMapInt64UintptrR, (*Decoder).fastpathDecMapInt64UintptrR)
-	fn(map[int64]int(nil), (*Encoder).fastpathEncMapInt64IntR, (*Decoder).fastpathDecMapInt64IntR)
-	fn(map[int64]int8(nil), (*Encoder).fastpathEncMapInt64Int8R, (*Decoder).fastpathDecMapInt64Int8R)
-	fn(map[int64]int16(nil), (*Encoder).fastpathEncMapInt64Int16R, (*Decoder).fastpathDecMapInt64Int16R)
-	fn(map[int64]int32(nil), (*Encoder).fastpathEncMapInt64Int32R, (*Decoder).fastpathDecMapInt64Int32R)
-	fn(map[int64]int64(nil), (*Encoder).fastpathEncMapInt64Int64R, (*Decoder).fastpathDecMapInt64Int64R)
-	fn(map[int64]float32(nil), (*Encoder).fastpathEncMapInt64Float32R, (*Decoder).fastpathDecMapInt64Float32R)
-	fn(map[int64]float64(nil), (*Encoder).fastpathEncMapInt64Float64R, (*Decoder).fastpathDecMapInt64Float64R)
-	fn(map[int64]bool(nil), (*Encoder).fastpathEncMapInt64BoolR, (*Decoder).fastpathDecMapInt64BoolR)
-	fn(map[bool]interface{}(nil), (*Encoder).fastpathEncMapBoolIntfR, (*Decoder).fastpathDecMapBoolIntfR)
-	fn(map[bool]string(nil), (*Encoder).fastpathEncMapBoolStringR, (*Decoder).fastpathDecMapBoolStringR)
-	fn(map[bool]uint(nil), (*Encoder).fastpathEncMapBoolUintR, (*Decoder).fastpathDecMapBoolUintR)
-	fn(map[bool]uint8(nil), (*Encoder).fastpathEncMapBoolUint8R, (*Decoder).fastpathDecMapBoolUint8R)
-	fn(map[bool]uint16(nil), (*Encoder).fastpathEncMapBoolUint16R, (*Decoder).fastpathDecMapBoolUint16R)
-	fn(map[bool]uint32(nil), (*Encoder).fastpathEncMapBoolUint32R, (*Decoder).fastpathDecMapBoolUint32R)
-	fn(map[bool]uint64(nil), (*Encoder).fastpathEncMapBoolUint64R, (*Decoder).fastpathDecMapBoolUint64R)
-	fn(map[bool]uintptr(nil), (*Encoder).fastpathEncMapBoolUintptrR, (*Decoder).fastpathDecMapBoolUintptrR)
-	fn(map[bool]int(nil), (*Encoder).fastpathEncMapBoolIntR, (*Decoder).fastpathDecMapBoolIntR)
-	fn(map[bool]int8(nil), (*Encoder).fastpathEncMapBoolInt8R, (*Decoder).fastpathDecMapBoolInt8R)
-	fn(map[bool]int16(nil), (*Encoder).fastpathEncMapBoolInt16R, (*Decoder).fastpathDecMapBoolInt16R)
-	fn(map[bool]int32(nil), (*Encoder).fastpathEncMapBoolInt32R, (*Decoder).fastpathDecMapBoolInt32R)
-	fn(map[bool]int64(nil), (*Encoder).fastpathEncMapBoolInt64R, (*Decoder).fastpathDecMapBoolInt64R)
-	fn(map[bool]float32(nil), (*Encoder).fastpathEncMapBoolFloat32R, (*Decoder).fastpathDecMapBoolFloat32R)
-	fn(map[bool]float64(nil), (*Encoder).fastpathEncMapBoolFloat64R, (*Decoder).fastpathDecMapBoolFloat64R)
-	fn(map[bool]bool(nil), (*Encoder).fastpathEncMapBoolBoolR, (*Decoder).fastpathDecMapBoolBoolR)
+	fn([]interface{}(nil), (*encFnInfo).fastpathEncSliceIntfR, (*decFnInfo).fastpathDecSliceIntfR)
+	fn([]string(nil), (*encFnInfo).fastpathEncSliceStringR, (*decFnInfo).fastpathDecSliceStringR)
+	fn([]float32(nil), (*encFnInfo).fastpathEncSliceFloat32R, (*decFnInfo).fastpathDecSliceFloat32R)
+	fn([]float64(nil), (*encFnInfo).fastpathEncSliceFloat64R, (*decFnInfo).fastpathDecSliceFloat64R)
+	fn([]uint(nil), (*encFnInfo).fastpathEncSliceUintR, (*decFnInfo).fastpathDecSliceUintR)
+	fn([]uint16(nil), (*encFnInfo).fastpathEncSliceUint16R, (*decFnInfo).fastpathDecSliceUint16R)
+	fn([]uint32(nil), (*encFnInfo).fastpathEncSliceUint32R, (*decFnInfo).fastpathDecSliceUint32R)
+	fn([]uint64(nil), (*encFnInfo).fastpathEncSliceUint64R, (*decFnInfo).fastpathDecSliceUint64R)
+	fn([]uintptr(nil), (*encFnInfo).fastpathEncSliceUintptrR, (*decFnInfo).fastpathDecSliceUintptrR)
+	fn([]int(nil), (*encFnInfo).fastpathEncSliceIntR, (*decFnInfo).fastpathDecSliceIntR)
+	fn([]int8(nil), (*encFnInfo).fastpathEncSliceInt8R, (*decFnInfo).fastpathDecSliceInt8R)
+	fn([]int16(nil), (*encFnInfo).fastpathEncSliceInt16R, (*decFnInfo).fastpathDecSliceInt16R)
+	fn([]int32(nil), (*encFnInfo).fastpathEncSliceInt32R, (*decFnInfo).fastpathDecSliceInt32R)
+	fn([]int64(nil), (*encFnInfo).fastpathEncSliceInt64R, (*decFnInfo).fastpathDecSliceInt64R)
+	fn([]bool(nil), (*encFnInfo).fastpathEncSliceBoolR, (*decFnInfo).fastpathDecSliceBoolR)
+
+	fn(map[interface{}]interface{}(nil), (*encFnInfo).fastpathEncMapIntfIntfR, (*decFnInfo).fastpathDecMapIntfIntfR)
+	fn(map[interface{}]string(nil), (*encFnInfo).fastpathEncMapIntfStringR, (*decFnInfo).fastpathDecMapIntfStringR)
+	fn(map[interface{}]uint(nil), (*encFnInfo).fastpathEncMapIntfUintR, (*decFnInfo).fastpathDecMapIntfUintR)
+	fn(map[interface{}]uint8(nil), (*encFnInfo).fastpathEncMapIntfUint8R, (*decFnInfo).fastpathDecMapIntfUint8R)
+	fn(map[interface{}]uint16(nil), (*encFnInfo).fastpathEncMapIntfUint16R, (*decFnInfo).fastpathDecMapIntfUint16R)
+	fn(map[interface{}]uint32(nil), (*encFnInfo).fastpathEncMapIntfUint32R, (*decFnInfo).fastpathDecMapIntfUint32R)
+	fn(map[interface{}]uint64(nil), (*encFnInfo).fastpathEncMapIntfUint64R, (*decFnInfo).fastpathDecMapIntfUint64R)
+	fn(map[interface{}]uintptr(nil), (*encFnInfo).fastpathEncMapIntfUintptrR, (*decFnInfo).fastpathDecMapIntfUintptrR)
+	fn(map[interface{}]int(nil), (*encFnInfo).fastpathEncMapIntfIntR, (*decFnInfo).fastpathDecMapIntfIntR)
+	fn(map[interface{}]int8(nil), (*encFnInfo).fastpathEncMapIntfInt8R, (*decFnInfo).fastpathDecMapIntfInt8R)
+	fn(map[interface{}]int16(nil), (*encFnInfo).fastpathEncMapIntfInt16R, (*decFnInfo).fastpathDecMapIntfInt16R)
+	fn(map[interface{}]int32(nil), (*encFnInfo).fastpathEncMapIntfInt32R, (*decFnInfo).fastpathDecMapIntfInt32R)
+	fn(map[interface{}]int64(nil), (*encFnInfo).fastpathEncMapIntfInt64R, (*decFnInfo).fastpathDecMapIntfInt64R)
+	fn(map[interface{}]float32(nil), (*encFnInfo).fastpathEncMapIntfFloat32R, (*decFnInfo).fastpathDecMapIntfFloat32R)
+	fn(map[interface{}]float64(nil), (*encFnInfo).fastpathEncMapIntfFloat64R, (*decFnInfo).fastpathDecMapIntfFloat64R)
+	fn(map[interface{}]bool(nil), (*encFnInfo).fastpathEncMapIntfBoolR, (*decFnInfo).fastpathDecMapIntfBoolR)
+	fn(map[string]interface{}(nil), (*encFnInfo).fastpathEncMapStringIntfR, (*decFnInfo).fastpathDecMapStringIntfR)
+	fn(map[string]string(nil), (*encFnInfo).fastpathEncMapStringStringR, (*decFnInfo).fastpathDecMapStringStringR)
+	fn(map[string]uint(nil), (*encFnInfo).fastpathEncMapStringUintR, (*decFnInfo).fastpathDecMapStringUintR)
+	fn(map[string]uint8(nil), (*encFnInfo).fastpathEncMapStringUint8R, (*decFnInfo).fastpathDecMapStringUint8R)
+	fn(map[string]uint16(nil), (*encFnInfo).fastpathEncMapStringUint16R, (*decFnInfo).fastpathDecMapStringUint16R)
+	fn(map[string]uint32(nil), (*encFnInfo).fastpathEncMapStringUint32R, (*decFnInfo).fastpathDecMapStringUint32R)
+	fn(map[string]uint64(nil), (*encFnInfo).fastpathEncMapStringUint64R, (*decFnInfo).fastpathDecMapStringUint64R)
+	fn(map[string]uintptr(nil), (*encFnInfo).fastpathEncMapStringUintptrR, (*decFnInfo).fastpathDecMapStringUintptrR)
+	fn(map[string]int(nil), (*encFnInfo).fastpathEncMapStringIntR, (*decFnInfo).fastpathDecMapStringIntR)
+	fn(map[string]int8(nil), (*encFnInfo).fastpathEncMapStringInt8R, (*decFnInfo).fastpathDecMapStringInt8R)
+	fn(map[string]int16(nil), (*encFnInfo).fastpathEncMapStringInt16R, (*decFnInfo).fastpathDecMapStringInt16R)
+	fn(map[string]int32(nil), (*encFnInfo).fastpathEncMapStringInt32R, (*decFnInfo).fastpathDecMapStringInt32R)
+	fn(map[string]int64(nil), (*encFnInfo).fastpathEncMapStringInt64R, (*decFnInfo).fastpathDecMapStringInt64R)
+	fn(map[string]float32(nil), (*encFnInfo).fastpathEncMapStringFloat32R, (*decFnInfo).fastpathDecMapStringFloat32R)
+	fn(map[string]float64(nil), (*encFnInfo).fastpathEncMapStringFloat64R, (*decFnInfo).fastpathDecMapStringFloat64R)
+	fn(map[string]bool(nil), (*encFnInfo).fastpathEncMapStringBoolR, (*decFnInfo).fastpathDecMapStringBoolR)
+	fn(map[float32]interface{}(nil), (*encFnInfo).fastpathEncMapFloat32IntfR, (*decFnInfo).fastpathDecMapFloat32IntfR)
+	fn(map[float32]string(nil), (*encFnInfo).fastpathEncMapFloat32StringR, (*decFnInfo).fastpathDecMapFloat32StringR)
+	fn(map[float32]uint(nil), (*encFnInfo).fastpathEncMapFloat32UintR, (*decFnInfo).fastpathDecMapFloat32UintR)
+	fn(map[float32]uint8(nil), (*encFnInfo).fastpathEncMapFloat32Uint8R, (*decFnInfo).fastpathDecMapFloat32Uint8R)
+	fn(map[float32]uint16(nil), (*encFnInfo).fastpathEncMapFloat32Uint16R, (*decFnInfo).fastpathDecMapFloat32Uint16R)
+	fn(map[float32]uint32(nil), (*encFnInfo).fastpathEncMapFloat32Uint32R, (*decFnInfo).fastpathDecMapFloat32Uint32R)
+	fn(map[float32]uint64(nil), (*encFnInfo).fastpathEncMapFloat32Uint64R, (*decFnInfo).fastpathDecMapFloat32Uint64R)
+	fn(map[float32]uintptr(nil), (*encFnInfo).fastpathEncMapFloat32UintptrR, (*decFnInfo).fastpathDecMapFloat32UintptrR)
+	fn(map[float32]int(nil), (*encFnInfo).fastpathEncMapFloat32IntR, (*decFnInfo).fastpathDecMapFloat32IntR)
+	fn(map[float32]int8(nil), (*encFnInfo).fastpathEncMapFloat32Int8R, (*decFnInfo).fastpathDecMapFloat32Int8R)
+	fn(map[float32]int16(nil), (*encFnInfo).fastpathEncMapFloat32Int16R, (*decFnInfo).fastpathDecMapFloat32Int16R)
+	fn(map[float32]int32(nil), (*encFnInfo).fastpathEncMapFloat32Int32R, (*decFnInfo).fastpathDecMapFloat32Int32R)
+	fn(map[float32]int64(nil), (*encFnInfo).fastpathEncMapFloat32Int64R, (*decFnInfo).fastpathDecMapFloat32Int64R)
+	fn(map[float32]float32(nil), (*encFnInfo).fastpathEncMapFloat32Float32R, (*decFnInfo).fastpathDecMapFloat32Float32R)
+	fn(map[float32]float64(nil), (*encFnInfo).fastpathEncMapFloat32Float64R, (*decFnInfo).fastpathDecMapFloat32Float64R)
+	fn(map[float32]bool(nil), (*encFnInfo).fastpathEncMapFloat32BoolR, (*decFnInfo).fastpathDecMapFloat32BoolR)
+	fn(map[float64]interface{}(nil), (*encFnInfo).fastpathEncMapFloat64IntfR, (*decFnInfo).fastpathDecMapFloat64IntfR)
+	fn(map[float64]string(nil), (*encFnInfo).fastpathEncMapFloat64StringR, (*decFnInfo).fastpathDecMapFloat64StringR)
+	fn(map[float64]uint(nil), (*encFnInfo).fastpathEncMapFloat64UintR, (*decFnInfo).fastpathDecMapFloat64UintR)
+	fn(map[float64]uint8(nil), (*encFnInfo).fastpathEncMapFloat64Uint8R, (*decFnInfo).fastpathDecMapFloat64Uint8R)
+	fn(map[float64]uint16(nil), (*encFnInfo).fastpathEncMapFloat64Uint16R, (*decFnInfo).fastpathDecMapFloat64Uint16R)
+	fn(map[float64]uint32(nil), (*encFnInfo).fastpathEncMapFloat64Uint32R, (*decFnInfo).fastpathDecMapFloat64Uint32R)
+	fn(map[float64]uint64(nil), (*encFnInfo).fastpathEncMapFloat64Uint64R, (*decFnInfo).fastpathDecMapFloat64Uint64R)
+	fn(map[float64]uintptr(nil), (*encFnInfo).fastpathEncMapFloat64UintptrR, (*decFnInfo).fastpathDecMapFloat64UintptrR)
+	fn(map[float64]int(nil), (*encFnInfo).fastpathEncMapFloat64IntR, (*decFnInfo).fastpathDecMapFloat64IntR)
+	fn(map[float64]int8(nil), (*encFnInfo).fastpathEncMapFloat64Int8R, (*decFnInfo).fastpathDecMapFloat64Int8R)
+	fn(map[float64]int16(nil), (*encFnInfo).fastpathEncMapFloat64Int16R, (*decFnInfo).fastpathDecMapFloat64Int16R)
+	fn(map[float64]int32(nil), (*encFnInfo).fastpathEncMapFloat64Int32R, (*decFnInfo).fastpathDecMapFloat64Int32R)
+	fn(map[float64]int64(nil), (*encFnInfo).fastpathEncMapFloat64Int64R, (*decFnInfo).fastpathDecMapFloat64Int64R)
+	fn(map[float64]float32(nil), (*encFnInfo).fastpathEncMapFloat64Float32R, (*decFnInfo).fastpathDecMapFloat64Float32R)
+	fn(map[float64]float64(nil), (*encFnInfo).fastpathEncMapFloat64Float64R, (*decFnInfo).fastpathDecMapFloat64Float64R)
+	fn(map[float64]bool(nil), (*encFnInfo).fastpathEncMapFloat64BoolR, (*decFnInfo).fastpathDecMapFloat64BoolR)
+	fn(map[uint]interface{}(nil), (*encFnInfo).fastpathEncMapUintIntfR, (*decFnInfo).fastpathDecMapUintIntfR)
+	fn(map[uint]string(nil), (*encFnInfo).fastpathEncMapUintStringR, (*decFnInfo).fastpathDecMapUintStringR)
+	fn(map[uint]uint(nil), (*encFnInfo).fastpathEncMapUintUintR, (*decFnInfo).fastpathDecMapUintUintR)
+	fn(map[uint]uint8(nil), (*encFnInfo).fastpathEncMapUintUint8R, (*decFnInfo).fastpathDecMapUintUint8R)
+	fn(map[uint]uint16(nil), (*encFnInfo).fastpathEncMapUintUint16R, (*decFnInfo).fastpathDecMapUintUint16R)
+	fn(map[uint]uint32(nil), (*encFnInfo).fastpathEncMapUintUint32R, (*decFnInfo).fastpathDecMapUintUint32R)
+	fn(map[uint]uint64(nil), (*encFnInfo).fastpathEncMapUintUint64R, (*decFnInfo).fastpathDecMapUintUint64R)
+	fn(map[uint]uintptr(nil), (*encFnInfo).fastpathEncMapUintUintptrR, (*decFnInfo).fastpathDecMapUintUintptrR)
+	fn(map[uint]int(nil), (*encFnInfo).fastpathEncMapUintIntR, (*decFnInfo).fastpathDecMapUintIntR)
+	fn(map[uint]int8(nil), (*encFnInfo).fastpathEncMapUintInt8R, (*decFnInfo).fastpathDecMapUintInt8R)
+	fn(map[uint]int16(nil), (*encFnInfo).fastpathEncMapUintInt16R, (*decFnInfo).fastpathDecMapUintInt16R)
+	fn(map[uint]int32(nil), (*encFnInfo).fastpathEncMapUintInt32R, (*decFnInfo).fastpathDecMapUintInt32R)
+	fn(map[uint]int64(nil), (*encFnInfo).fastpathEncMapUintInt64R, (*decFnInfo).fastpathDecMapUintInt64R)
+	fn(map[uint]float32(nil), (*encFnInfo).fastpathEncMapUintFloat32R, (*decFnInfo).fastpathDecMapUintFloat32R)
+	fn(map[uint]float64(nil), (*encFnInfo).fastpathEncMapUintFloat64R, (*decFnInfo).fastpathDecMapUintFloat64R)
+	fn(map[uint]bool(nil), (*encFnInfo).fastpathEncMapUintBoolR, (*decFnInfo).fastpathDecMapUintBoolR)
+	fn(map[uint8]interface{}(nil), (*encFnInfo).fastpathEncMapUint8IntfR, (*decFnInfo).fastpathDecMapUint8IntfR)
+	fn(map[uint8]string(nil), (*encFnInfo).fastpathEncMapUint8StringR, (*decFnInfo).fastpathDecMapUint8StringR)
+	fn(map[uint8]uint(nil), (*encFnInfo).fastpathEncMapUint8UintR, (*decFnInfo).fastpathDecMapUint8UintR)
+	fn(map[uint8]uint8(nil), (*encFnInfo).fastpathEncMapUint8Uint8R, (*decFnInfo).fastpathDecMapUint8Uint8R)
+	fn(map[uint8]uint16(nil), (*encFnInfo).fastpathEncMapUint8Uint16R, (*decFnInfo).fastpathDecMapUint8Uint16R)
+	fn(map[uint8]uint32(nil), (*encFnInfo).fastpathEncMapUint8Uint32R, (*decFnInfo).fastpathDecMapUint8Uint32R)
+	fn(map[uint8]uint64(nil), (*encFnInfo).fastpathEncMapUint8Uint64R, (*decFnInfo).fastpathDecMapUint8Uint64R)
+	fn(map[uint8]uintptr(nil), (*encFnInfo).fastpathEncMapUint8UintptrR, (*decFnInfo).fastpathDecMapUint8UintptrR)
+	fn(map[uint8]int(nil), (*encFnInfo).fastpathEncMapUint8IntR, (*decFnInfo).fastpathDecMapUint8IntR)
+	fn(map[uint8]int8(nil), (*encFnInfo).fastpathEncMapUint8Int8R, (*decFnInfo).fastpathDecMapUint8Int8R)
+	fn(map[uint8]int16(nil), (*encFnInfo).fastpathEncMapUint8Int16R, (*decFnInfo).fastpathDecMapUint8Int16R)
+	fn(map[uint8]int32(nil), (*encFnInfo).fastpathEncMapUint8Int32R, (*decFnInfo).fastpathDecMapUint8Int32R)
+	fn(map[uint8]int64(nil), (*encFnInfo).fastpathEncMapUint8Int64R, (*decFnInfo).fastpathDecMapUint8Int64R)
+	fn(map[uint8]float32(nil), (*encFnInfo).fastpathEncMapUint8Float32R, (*decFnInfo).fastpathDecMapUint8Float32R)
+	fn(map[uint8]float64(nil), (*encFnInfo).fastpathEncMapUint8Float64R, (*decFnInfo).fastpathDecMapUint8Float64R)
+	fn(map[uint8]bool(nil), (*encFnInfo).fastpathEncMapUint8BoolR, (*decFnInfo).fastpathDecMapUint8BoolR)
+	fn(map[uint16]interface{}(nil), (*encFnInfo).fastpathEncMapUint16IntfR, (*decFnInfo).fastpathDecMapUint16IntfR)
+	fn(map[uint16]string(nil), (*encFnInfo).fastpathEncMapUint16StringR, (*decFnInfo).fastpathDecMapUint16StringR)
+	fn(map[uint16]uint(nil), (*encFnInfo).fastpathEncMapUint16UintR, (*decFnInfo).fastpathDecMapUint16UintR)
+	fn(map[uint16]uint8(nil), (*encFnInfo).fastpathEncMapUint16Uint8R, (*decFnInfo).fastpathDecMapUint16Uint8R)
+	fn(map[uint16]uint16(nil), (*encFnInfo).fastpathEncMapUint16Uint16R, (*decFnInfo).fastpathDecMapUint16Uint16R)
+	fn(map[uint16]uint32(nil), (*encFnInfo).fastpathEncMapUint16Uint32R, (*decFnInfo).fastpathDecMapUint16Uint32R)
+	fn(map[uint16]uint64(nil), (*encFnInfo).fastpathEncMapUint16Uint64R, (*decFnInfo).fastpathDecMapUint16Uint64R)
+	fn(map[uint16]uintptr(nil), (*encFnInfo).fastpathEncMapUint16UintptrR, (*decFnInfo).fastpathDecMapUint16UintptrR)
+	fn(map[uint16]int(nil), (*encFnInfo).fastpathEncMapUint16IntR, (*decFnInfo).fastpathDecMapUint16IntR)
+	fn(map[uint16]int8(nil), (*encFnInfo).fastpathEncMapUint16Int8R, (*decFnInfo).fastpathDecMapUint16Int8R)
+	fn(map[uint16]int16(nil), (*encFnInfo).fastpathEncMapUint16Int16R, (*decFnInfo).fastpathDecMapUint16Int16R)
+	fn(map[uint16]int32(nil), (*encFnInfo).fastpathEncMapUint16Int32R, (*decFnInfo).fastpathDecMapUint16Int32R)
+	fn(map[uint16]int64(nil), (*encFnInfo).fastpathEncMapUint16Int64R, (*decFnInfo).fastpathDecMapUint16Int64R)
+	fn(map[uint16]float32(nil), (*encFnInfo).fastpathEncMapUint16Float32R, (*decFnInfo).fastpathDecMapUint16Float32R)
+	fn(map[uint16]float64(nil), (*encFnInfo).fastpathEncMapUint16Float64R, (*decFnInfo).fastpathDecMapUint16Float64R)
+	fn(map[uint16]bool(nil), (*encFnInfo).fastpathEncMapUint16BoolR, (*decFnInfo).fastpathDecMapUint16BoolR)
+	fn(map[uint32]interface{}(nil), (*encFnInfo).fastpathEncMapUint32IntfR, (*decFnInfo).fastpathDecMapUint32IntfR)
+	fn(map[uint32]string(nil), (*encFnInfo).fastpathEncMapUint32StringR, (*decFnInfo).fastpathDecMapUint32StringR)
+	fn(map[uint32]uint(nil), (*encFnInfo).fastpathEncMapUint32UintR, (*decFnInfo).fastpathDecMapUint32UintR)
+	fn(map[uint32]uint8(nil), (*encFnInfo).fastpathEncMapUint32Uint8R, (*decFnInfo).fastpathDecMapUint32Uint8R)
+	fn(map[uint32]uint16(nil), (*encFnInfo).fastpathEncMapUint32Uint16R, (*decFnInfo).fastpathDecMapUint32Uint16R)
+	fn(map[uint32]uint32(nil), (*encFnInfo).fastpathEncMapUint32Uint32R, (*decFnInfo).fastpathDecMapUint32Uint32R)
+	fn(map[uint32]uint64(nil), (*encFnInfo).fastpathEncMapUint32Uint64R, (*decFnInfo).fastpathDecMapUint32Uint64R)
+	fn(map[uint32]uintptr(nil), (*encFnInfo).fastpathEncMapUint32UintptrR, (*decFnInfo).fastpathDecMapUint32UintptrR)
+	fn(map[uint32]int(nil), (*encFnInfo).fastpathEncMapUint32IntR, (*decFnInfo).fastpathDecMapUint32IntR)
+	fn(map[uint32]int8(nil), (*encFnInfo).fastpathEncMapUint32Int8R, (*decFnInfo).fastpathDecMapUint32Int8R)
+	fn(map[uint32]int16(nil), (*encFnInfo).fastpathEncMapUint32Int16R, (*decFnInfo).fastpathDecMapUint32Int16R)
+	fn(map[uint32]int32(nil), (*encFnInfo).fastpathEncMapUint32Int32R, (*decFnInfo).fastpathDecMapUint32Int32R)
+	fn(map[uint32]int64(nil), (*encFnInfo).fastpathEncMapUint32Int64R, (*decFnInfo).fastpathDecMapUint32Int64R)
+	fn(map[uint32]float32(nil), (*encFnInfo).fastpathEncMapUint32Float32R, (*decFnInfo).fastpathDecMapUint32Float32R)
+	fn(map[uint32]float64(nil), (*encFnInfo).fastpathEncMapUint32Float64R, (*decFnInfo).fastpathDecMapUint32Float64R)
+	fn(map[uint32]bool(nil), (*encFnInfo).fastpathEncMapUint32BoolR, (*decFnInfo).fastpathDecMapUint32BoolR)
+	fn(map[uint64]interface{}(nil), (*encFnInfo).fastpathEncMapUint64IntfR, (*decFnInfo).fastpathDecMapUint64IntfR)
+	fn(map[uint64]string(nil), (*encFnInfo).fastpathEncMapUint64StringR, (*decFnInfo).fastpathDecMapUint64StringR)
+	fn(map[uint64]uint(nil), (*encFnInfo).fastpathEncMapUint64UintR, (*decFnInfo).fastpathDecMapUint64UintR)
+	fn(map[uint64]uint8(nil), (*encFnInfo).fastpathEncMapUint64Uint8R, (*decFnInfo).fastpathDecMapUint64Uint8R)
+	fn(map[uint64]uint16(nil), (*encFnInfo).fastpathEncMapUint64Uint16R, (*decFnInfo).fastpathDecMapUint64Uint16R)
+	fn(map[uint64]uint32(nil), (*encFnInfo).fastpathEncMapUint64Uint32R, (*decFnInfo).fastpathDecMapUint64Uint32R)
+	fn(map[uint64]uint64(nil), (*encFnInfo).fastpathEncMapUint64Uint64R, (*decFnInfo).fastpathDecMapUint64Uint64R)
+	fn(map[uint64]uintptr(nil), (*encFnInfo).fastpathEncMapUint64UintptrR, (*decFnInfo).fastpathDecMapUint64UintptrR)
+	fn(map[uint64]int(nil), (*encFnInfo).fastpathEncMapUint64IntR, (*decFnInfo).fastpathDecMapUint64IntR)
+	fn(map[uint64]int8(nil), (*encFnInfo).fastpathEncMapUint64Int8R, (*decFnInfo).fastpathDecMapUint64Int8R)
+	fn(map[uint64]int16(nil), (*encFnInfo).fastpathEncMapUint64Int16R, (*decFnInfo).fastpathDecMapUint64Int16R)
+	fn(map[uint64]int32(nil), (*encFnInfo).fastpathEncMapUint64Int32R, (*decFnInfo).fastpathDecMapUint64Int32R)
+	fn(map[uint64]int64(nil), (*encFnInfo).fastpathEncMapUint64Int64R, (*decFnInfo).fastpathDecMapUint64Int64R)
+	fn(map[uint64]float32(nil), (*encFnInfo).fastpathEncMapUint64Float32R, (*decFnInfo).fastpathDecMapUint64Float32R)
+	fn(map[uint64]float64(nil), (*encFnInfo).fastpathEncMapUint64Float64R, (*decFnInfo).fastpathDecMapUint64Float64R)
+	fn(map[uint64]bool(nil), (*encFnInfo).fastpathEncMapUint64BoolR, (*decFnInfo).fastpathDecMapUint64BoolR)
+	fn(map[uintptr]interface{}(nil), (*encFnInfo).fastpathEncMapUintptrIntfR, (*decFnInfo).fastpathDecMapUintptrIntfR)
+	fn(map[uintptr]string(nil), (*encFnInfo).fastpathEncMapUintptrStringR, (*decFnInfo).fastpathDecMapUintptrStringR)
+	fn(map[uintptr]uint(nil), (*encFnInfo).fastpathEncMapUintptrUintR, (*decFnInfo).fastpathDecMapUintptrUintR)
+	fn(map[uintptr]uint8(nil), (*encFnInfo).fastpathEncMapUintptrUint8R, (*decFnInfo).fastpathDecMapUintptrUint8R)
+	fn(map[uintptr]uint16(nil), (*encFnInfo).fastpathEncMapUintptrUint16R, (*decFnInfo).fastpathDecMapUintptrUint16R)
+	fn(map[uintptr]uint32(nil), (*encFnInfo).fastpathEncMapUintptrUint32R, (*decFnInfo).fastpathDecMapUintptrUint32R)
+	fn(map[uintptr]uint64(nil), (*encFnInfo).fastpathEncMapUintptrUint64R, (*decFnInfo).fastpathDecMapUintptrUint64R)
+	fn(map[uintptr]uintptr(nil), (*encFnInfo).fastpathEncMapUintptrUintptrR, (*decFnInfo).fastpathDecMapUintptrUintptrR)
+	fn(map[uintptr]int(nil), (*encFnInfo).fastpathEncMapUintptrIntR, (*decFnInfo).fastpathDecMapUintptrIntR)
+	fn(map[uintptr]int8(nil), (*encFnInfo).fastpathEncMapUintptrInt8R, (*decFnInfo).fastpathDecMapUintptrInt8R)
+	fn(map[uintptr]int16(nil), (*encFnInfo).fastpathEncMapUintptrInt16R, (*decFnInfo).fastpathDecMapUintptrInt16R)
+	fn(map[uintptr]int32(nil), (*encFnInfo).fastpathEncMapUintptrInt32R, (*decFnInfo).fastpathDecMapUintptrInt32R)
+	fn(map[uintptr]int64(nil), (*encFnInfo).fastpathEncMapUintptrInt64R, (*decFnInfo).fastpathDecMapUintptrInt64R)
+	fn(map[uintptr]float32(nil), (*encFnInfo).fastpathEncMapUintptrFloat32R, (*decFnInfo).fastpathDecMapUintptrFloat32R)
+	fn(map[uintptr]float64(nil), (*encFnInfo).fastpathEncMapUintptrFloat64R, (*decFnInfo).fastpathDecMapUintptrFloat64R)
+	fn(map[uintptr]bool(nil), (*encFnInfo).fastpathEncMapUintptrBoolR, (*decFnInfo).fastpathDecMapUintptrBoolR)
+	fn(map[int]interface{}(nil), (*encFnInfo).fastpathEncMapIntIntfR, (*decFnInfo).fastpathDecMapIntIntfR)
+	fn(map[int]string(nil), (*encFnInfo).fastpathEncMapIntStringR, (*decFnInfo).fastpathDecMapIntStringR)
+	fn(map[int]uint(nil), (*encFnInfo).fastpathEncMapIntUintR, (*decFnInfo).fastpathDecMapIntUintR)
+	fn(map[int]uint8(nil), (*encFnInfo).fastpathEncMapIntUint8R, (*decFnInfo).fastpathDecMapIntUint8R)
+	fn(map[int]uint16(nil), (*encFnInfo).fastpathEncMapIntUint16R, (*decFnInfo).fastpathDecMapIntUint16R)
+	fn(map[int]uint32(nil), (*encFnInfo).fastpathEncMapIntUint32R, (*decFnInfo).fastpathDecMapIntUint32R)
+	fn(map[int]uint64(nil), (*encFnInfo).fastpathEncMapIntUint64R, (*decFnInfo).fastpathDecMapIntUint64R)
+	fn(map[int]uintptr(nil), (*encFnInfo).fastpathEncMapIntUintptrR, (*decFnInfo).fastpathDecMapIntUintptrR)
+	fn(map[int]int(nil), (*encFnInfo).fastpathEncMapIntIntR, (*decFnInfo).fastpathDecMapIntIntR)
+	fn(map[int]int8(nil), (*encFnInfo).fastpathEncMapIntInt8R, (*decFnInfo).fastpathDecMapIntInt8R)
+	fn(map[int]int16(nil), (*encFnInfo).fastpathEncMapIntInt16R, (*decFnInfo).fastpathDecMapIntInt16R)
+	fn(map[int]int32(nil), (*encFnInfo).fastpathEncMapIntInt32R, (*decFnInfo).fastpathDecMapIntInt32R)
+	fn(map[int]int64(nil), (*encFnInfo).fastpathEncMapIntInt64R, (*decFnInfo).fastpathDecMapIntInt64R)
+	fn(map[int]float32(nil), (*encFnInfo).fastpathEncMapIntFloat32R, (*decFnInfo).fastpathDecMapIntFloat32R)
+	fn(map[int]float64(nil), (*encFnInfo).fastpathEncMapIntFloat64R, (*decFnInfo).fastpathDecMapIntFloat64R)
+	fn(map[int]bool(nil), (*encFnInfo).fastpathEncMapIntBoolR, (*decFnInfo).fastpathDecMapIntBoolR)
+	fn(map[int8]interface{}(nil), (*encFnInfo).fastpathEncMapInt8IntfR, (*decFnInfo).fastpathDecMapInt8IntfR)
+	fn(map[int8]string(nil), (*encFnInfo).fastpathEncMapInt8StringR, (*decFnInfo).fastpathDecMapInt8StringR)
+	fn(map[int8]uint(nil), (*encFnInfo).fastpathEncMapInt8UintR, (*decFnInfo).fastpathDecMapInt8UintR)
+	fn(map[int8]uint8(nil), (*encFnInfo).fastpathEncMapInt8Uint8R, (*decFnInfo).fastpathDecMapInt8Uint8R)
+	fn(map[int8]uint16(nil), (*encFnInfo).fastpathEncMapInt8Uint16R, (*decFnInfo).fastpathDecMapInt8Uint16R)
+	fn(map[int8]uint32(nil), (*encFnInfo).fastpathEncMapInt8Uint32R, (*decFnInfo).fastpathDecMapInt8Uint32R)
+	fn(map[int8]uint64(nil), (*encFnInfo).fastpathEncMapInt8Uint64R, (*decFnInfo).fastpathDecMapInt8Uint64R)
+	fn(map[int8]uintptr(nil), (*encFnInfo).fastpathEncMapInt8UintptrR, (*decFnInfo).fastpathDecMapInt8UintptrR)
+	fn(map[int8]int(nil), (*encFnInfo).fastpathEncMapInt8IntR, (*decFnInfo).fastpathDecMapInt8IntR)
+	fn(map[int8]int8(nil), (*encFnInfo).fastpathEncMapInt8Int8R, (*decFnInfo).fastpathDecMapInt8Int8R)
+	fn(map[int8]int16(nil), (*encFnInfo).fastpathEncMapInt8Int16R, (*decFnInfo).fastpathDecMapInt8Int16R)
+	fn(map[int8]int32(nil), (*encFnInfo).fastpathEncMapInt8Int32R, (*decFnInfo).fastpathDecMapInt8Int32R)
+	fn(map[int8]int64(nil), (*encFnInfo).fastpathEncMapInt8Int64R, (*decFnInfo).fastpathDecMapInt8Int64R)
+	fn(map[int8]float32(nil), (*encFnInfo).fastpathEncMapInt8Float32R, (*decFnInfo).fastpathDecMapInt8Float32R)
+	fn(map[int8]float64(nil), (*encFnInfo).fastpathEncMapInt8Float64R, (*decFnInfo).fastpathDecMapInt8Float64R)
+	fn(map[int8]bool(nil), (*encFnInfo).fastpathEncMapInt8BoolR, (*decFnInfo).fastpathDecMapInt8BoolR)
+	fn(map[int16]interface{}(nil), (*encFnInfo).fastpathEncMapInt16IntfR, (*decFnInfo).fastpathDecMapInt16IntfR)
+	fn(map[int16]string(nil), (*encFnInfo).fastpathEncMapInt16StringR, (*decFnInfo).fastpathDecMapInt16StringR)
+	fn(map[int16]uint(nil), (*encFnInfo).fastpathEncMapInt16UintR, (*decFnInfo).fastpathDecMapInt16UintR)
+	fn(map[int16]uint8(nil), (*encFnInfo).fastpathEncMapInt16Uint8R, (*decFnInfo).fastpathDecMapInt16Uint8R)
+	fn(map[int16]uint16(nil), (*encFnInfo).fastpathEncMapInt16Uint16R, (*decFnInfo).fastpathDecMapInt16Uint16R)
+	fn(map[int16]uint32(nil), (*encFnInfo).fastpathEncMapInt16Uint32R, (*decFnInfo).fastpathDecMapInt16Uint32R)
+	fn(map[int16]uint64(nil), (*encFnInfo).fastpathEncMapInt16Uint64R, (*decFnInfo).fastpathDecMapInt16Uint64R)
+	fn(map[int16]uintptr(nil), (*encFnInfo).fastpathEncMapInt16UintptrR, (*decFnInfo).fastpathDecMapInt16UintptrR)
+	fn(map[int16]int(nil), (*encFnInfo).fastpathEncMapInt16IntR, (*decFnInfo).fastpathDecMapInt16IntR)
+	fn(map[int16]int8(nil), (*encFnInfo).fastpathEncMapInt16Int8R, (*decFnInfo).fastpathDecMapInt16Int8R)
+	fn(map[int16]int16(nil), (*encFnInfo).fastpathEncMapInt16Int16R, (*decFnInfo).fastpathDecMapInt16Int16R)
+	fn(map[int16]int32(nil), (*encFnInfo).fastpathEncMapInt16Int32R, (*decFnInfo).fastpathDecMapInt16Int32R)
+	fn(map[int16]int64(nil), (*encFnInfo).fastpathEncMapInt16Int64R, (*decFnInfo).fastpathDecMapInt16Int64R)
+	fn(map[int16]float32(nil), (*encFnInfo).fastpathEncMapInt16Float32R, (*decFnInfo).fastpathDecMapInt16Float32R)
+	fn(map[int16]float64(nil), (*encFnInfo).fastpathEncMapInt16Float64R, (*decFnInfo).fastpathDecMapInt16Float64R)
+	fn(map[int16]bool(nil), (*encFnInfo).fastpathEncMapInt16BoolR, (*decFnInfo).fastpathDecMapInt16BoolR)
+	fn(map[int32]interface{}(nil), (*encFnInfo).fastpathEncMapInt32IntfR, (*decFnInfo).fastpathDecMapInt32IntfR)
+	fn(map[int32]string(nil), (*encFnInfo).fastpathEncMapInt32StringR, (*decFnInfo).fastpathDecMapInt32StringR)
+	fn(map[int32]uint(nil), (*encFnInfo).fastpathEncMapInt32UintR, (*decFnInfo).fastpathDecMapInt32UintR)
+	fn(map[int32]uint8(nil), (*encFnInfo).fastpathEncMapInt32Uint8R, (*decFnInfo).fastpathDecMapInt32Uint8R)
+	fn(map[int32]uint16(nil), (*encFnInfo).fastpathEncMapInt32Uint16R, (*decFnInfo).fastpathDecMapInt32Uint16R)
+	fn(map[int32]uint32(nil), (*encFnInfo).fastpathEncMapInt32Uint32R, (*decFnInfo).fastpathDecMapInt32Uint32R)
+	fn(map[int32]uint64(nil), (*encFnInfo).fastpathEncMapInt32Uint64R, (*decFnInfo).fastpathDecMapInt32Uint64R)
+	fn(map[int32]uintptr(nil), (*encFnInfo).fastpathEncMapInt32UintptrR, (*decFnInfo).fastpathDecMapInt32UintptrR)
+	fn(map[int32]int(nil), (*encFnInfo).fastpathEncMapInt32IntR, (*decFnInfo).fastpathDecMapInt32IntR)
+	fn(map[int32]int8(nil), (*encFnInfo).fastpathEncMapInt32Int8R, (*decFnInfo).fastpathDecMapInt32Int8R)
+	fn(map[int32]int16(nil), (*encFnInfo).fastpathEncMapInt32Int16R, (*decFnInfo).fastpathDecMapInt32Int16R)
+	fn(map[int32]int32(nil), (*encFnInfo).fastpathEncMapInt32Int32R, (*decFnInfo).fastpathDecMapInt32Int32R)
+	fn(map[int32]int64(nil), (*encFnInfo).fastpathEncMapInt32Int64R, (*decFnInfo).fastpathDecMapInt32Int64R)
+	fn(map[int32]float32(nil), (*encFnInfo).fastpathEncMapInt32Float32R, (*decFnInfo).fastpathDecMapInt32Float32R)
+	fn(map[int32]float64(nil), (*encFnInfo).fastpathEncMapInt32Float64R, (*decFnInfo).fastpathDecMapInt32Float64R)
+	fn(map[int32]bool(nil), (*encFnInfo).fastpathEncMapInt32BoolR, (*decFnInfo).fastpathDecMapInt32BoolR)
+	fn(map[int64]interface{}(nil), (*encFnInfo).fastpathEncMapInt64IntfR, (*decFnInfo).fastpathDecMapInt64IntfR)
+	fn(map[int64]string(nil), (*encFnInfo).fastpathEncMapInt64StringR, (*decFnInfo).fastpathDecMapInt64StringR)
+	fn(map[int64]uint(nil), (*encFnInfo).fastpathEncMapInt64UintR, (*decFnInfo).fastpathDecMapInt64UintR)
+	fn(map[int64]uint8(nil), (*encFnInfo).fastpathEncMapInt64Uint8R, (*decFnInfo).fastpathDecMapInt64Uint8R)
+	fn(map[int64]uint16(nil), (*encFnInfo).fastpathEncMapInt64Uint16R, (*decFnInfo).fastpathDecMapInt64Uint16R)
+	fn(map[int64]uint32(nil), (*encFnInfo).fastpathEncMapInt64Uint32R, (*decFnInfo).fastpathDecMapInt64Uint32R)
+	fn(map[int64]uint64(nil), (*encFnInfo).fastpathEncMapInt64Uint64R, (*decFnInfo).fastpathDecMapInt64Uint64R)
+	fn(map[int64]uintptr(nil), (*encFnInfo).fastpathEncMapInt64UintptrR, (*decFnInfo).fastpathDecMapInt64UintptrR)
+	fn(map[int64]int(nil), (*encFnInfo).fastpathEncMapInt64IntR, (*decFnInfo).fastpathDecMapInt64IntR)
+	fn(map[int64]int8(nil), (*encFnInfo).fastpathEncMapInt64Int8R, (*decFnInfo).fastpathDecMapInt64Int8R)
+	fn(map[int64]int16(nil), (*encFnInfo).fastpathEncMapInt64Int16R, (*decFnInfo).fastpathDecMapInt64Int16R)
+	fn(map[int64]int32(nil), (*encFnInfo).fastpathEncMapInt64Int32R, (*decFnInfo).fastpathDecMapInt64Int32R)
+	fn(map[int64]int64(nil), (*encFnInfo).fastpathEncMapInt64Int64R, (*decFnInfo).fastpathDecMapInt64Int64R)
+	fn(map[int64]float32(nil), (*encFnInfo).fastpathEncMapInt64Float32R, (*decFnInfo).fastpathDecMapInt64Float32R)
+	fn(map[int64]float64(nil), (*encFnInfo).fastpathEncMapInt64Float64R, (*decFnInfo).fastpathDecMapInt64Float64R)
+	fn(map[int64]bool(nil), (*encFnInfo).fastpathEncMapInt64BoolR, (*decFnInfo).fastpathDecMapInt64BoolR)
+	fn(map[bool]interface{}(nil), (*encFnInfo).fastpathEncMapBoolIntfR, (*decFnInfo).fastpathDecMapBoolIntfR)
+	fn(map[bool]string(nil), (*encFnInfo).fastpathEncMapBoolStringR, (*decFnInfo).fastpathDecMapBoolStringR)
+	fn(map[bool]uint(nil), (*encFnInfo).fastpathEncMapBoolUintR, (*decFnInfo).fastpathDecMapBoolUintR)
+	fn(map[bool]uint8(nil), (*encFnInfo).fastpathEncMapBoolUint8R, (*decFnInfo).fastpathDecMapBoolUint8R)
+	fn(map[bool]uint16(nil), (*encFnInfo).fastpathEncMapBoolUint16R, (*decFnInfo).fastpathDecMapBoolUint16R)
+	fn(map[bool]uint32(nil), (*encFnInfo).fastpathEncMapBoolUint32R, (*decFnInfo).fastpathDecMapBoolUint32R)
+	fn(map[bool]uint64(nil), (*encFnInfo).fastpathEncMapBoolUint64R, (*decFnInfo).fastpathDecMapBoolUint64R)
+	fn(map[bool]uintptr(nil), (*encFnInfo).fastpathEncMapBoolUintptrR, (*decFnInfo).fastpathDecMapBoolUintptrR)
+	fn(map[bool]int(nil), (*encFnInfo).fastpathEncMapBoolIntR, (*decFnInfo).fastpathDecMapBoolIntR)
+	fn(map[bool]int8(nil), (*encFnInfo).fastpathEncMapBoolInt8R, (*decFnInfo).fastpathDecMapBoolInt8R)
+	fn(map[bool]int16(nil), (*encFnInfo).fastpathEncMapBoolInt16R, (*decFnInfo).fastpathDecMapBoolInt16R)
+	fn(map[bool]int32(nil), (*encFnInfo).fastpathEncMapBoolInt32R, (*decFnInfo).fastpathDecMapBoolInt32R)
+	fn(map[bool]int64(nil), (*encFnInfo).fastpathEncMapBoolInt64R, (*decFnInfo).fastpathDecMapBoolInt64R)
+	fn(map[bool]float32(nil), (*encFnInfo).fastpathEncMapBoolFloat32R, (*decFnInfo).fastpathDecMapBoolFloat32R)
+	fn(map[bool]float64(nil), (*encFnInfo).fastpathEncMapBoolFloat64R, (*decFnInfo).fastpathDecMapBoolFloat64R)
+	fn(map[bool]bool(nil), (*encFnInfo).fastpathEncMapBoolBoolR, (*decFnInfo).fastpathDecMapBoolBoolR)
 
 	sort.Sort(fastpathAslice(fastpathAV[:]))
 }
@@ -371,8098 +375,6750 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
 	switch v := iv.(type) {
 
 	case []interface{}:
-		fastpathTV.EncSliceIntfV(v, e)
+		fastpathTV.EncSliceIntfV(v, fastpathCheckNilTrue, e)
 	case *[]interface{}:
-		fastpathTV.EncSliceIntfV(*v, e)
-	case []string:
-		fastpathTV.EncSliceStringV(v, e)
-	case *[]string:
-		fastpathTV.EncSliceStringV(*v, e)
-	case []float32:
-		fastpathTV.EncSliceFloat32V(v, e)
-	case *[]float32:
-		fastpathTV.EncSliceFloat32V(*v, e)
-	case []float64:
-		fastpathTV.EncSliceFloat64V(v, e)
-	case *[]float64:
-		fastpathTV.EncSliceFloat64V(*v, e)
-	case []uint:
-		fastpathTV.EncSliceUintV(v, e)
-	case *[]uint:
-		fastpathTV.EncSliceUintV(*v, e)
-	case []uint16:
-		fastpathTV.EncSliceUint16V(v, e)
-	case *[]uint16:
-		fastpathTV.EncSliceUint16V(*v, e)
-	case []uint32:
-		fastpathTV.EncSliceUint32V(v, e)
-	case *[]uint32:
-		fastpathTV.EncSliceUint32V(*v, e)
-	case []uint64:
-		fastpathTV.EncSliceUint64V(v, e)
-	case *[]uint64:
-		fastpathTV.EncSliceUint64V(*v, e)
-	case []uintptr:
-		fastpathTV.EncSliceUintptrV(v, e)
-	case *[]uintptr:
-		fastpathTV.EncSliceUintptrV(*v, e)
-	case []int:
-		fastpathTV.EncSliceIntV(v, e)
-	case *[]int:
-		fastpathTV.EncSliceIntV(*v, e)
-	case []int8:
-		fastpathTV.EncSliceInt8V(v, e)
-	case *[]int8:
-		fastpathTV.EncSliceInt8V(*v, e)
-	case []int16:
-		fastpathTV.EncSliceInt16V(v, e)
-	case *[]int16:
-		fastpathTV.EncSliceInt16V(*v, e)
-	case []int32:
-		fastpathTV.EncSliceInt32V(v, e)
-	case *[]int32:
-		fastpathTV.EncSliceInt32V(*v, e)
-	case []int64:
-		fastpathTV.EncSliceInt64V(v, e)
-	case *[]int64:
-		fastpathTV.EncSliceInt64V(*v, e)
-	case []bool:
-		fastpathTV.EncSliceBoolV(v, e)
-	case *[]bool:
-		fastpathTV.EncSliceBoolV(*v, e)
+		fastpathTV.EncSliceIntfV(*v, fastpathCheckNilTrue, e)
 
 	case map[interface{}]interface{}:
-		fastpathTV.EncMapIntfIntfV(v, e)
+		fastpathTV.EncMapIntfIntfV(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]interface{}:
-		fastpathTV.EncMapIntfIntfV(*v, e)
+		fastpathTV.EncMapIntfIntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]string:
-		fastpathTV.EncMapIntfStringV(v, e)
+		fastpathTV.EncMapIntfStringV(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]string:
-		fastpathTV.EncMapIntfStringV(*v, e)
+		fastpathTV.EncMapIntfStringV(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]uint:
-		fastpathTV.EncMapIntfUintV(v, e)
+		fastpathTV.EncMapIntfUintV(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]uint:
-		fastpathTV.EncMapIntfUintV(*v, e)
+		fastpathTV.EncMapIntfUintV(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]uint8:
-		fastpathTV.EncMapIntfUint8V(v, e)
+		fastpathTV.EncMapIntfUint8V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]uint8:
-		fastpathTV.EncMapIntfUint8V(*v, e)
+		fastpathTV.EncMapIntfUint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]uint16:
-		fastpathTV.EncMapIntfUint16V(v, e)
+		fastpathTV.EncMapIntfUint16V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]uint16:
-		fastpathTV.EncMapIntfUint16V(*v, e)
+		fastpathTV.EncMapIntfUint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]uint32:
-		fastpathTV.EncMapIntfUint32V(v, e)
+		fastpathTV.EncMapIntfUint32V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]uint32:
-		fastpathTV.EncMapIntfUint32V(*v, e)
+		fastpathTV.EncMapIntfUint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]uint64:
-		fastpathTV.EncMapIntfUint64V(v, e)
+		fastpathTV.EncMapIntfUint64V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]uint64:
-		fastpathTV.EncMapIntfUint64V(*v, e)
+		fastpathTV.EncMapIntfUint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]uintptr:
-		fastpathTV.EncMapIntfUintptrV(v, e)
+		fastpathTV.EncMapIntfUintptrV(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]uintptr:
-		fastpathTV.EncMapIntfUintptrV(*v, e)
+		fastpathTV.EncMapIntfUintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]int:
-		fastpathTV.EncMapIntfIntV(v, e)
+		fastpathTV.EncMapIntfIntV(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]int:
-		fastpathTV.EncMapIntfIntV(*v, e)
+		fastpathTV.EncMapIntfIntV(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]int8:
-		fastpathTV.EncMapIntfInt8V(v, e)
+		fastpathTV.EncMapIntfInt8V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]int8:
-		fastpathTV.EncMapIntfInt8V(*v, e)
+		fastpathTV.EncMapIntfInt8V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]int16:
-		fastpathTV.EncMapIntfInt16V(v, e)
+		fastpathTV.EncMapIntfInt16V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]int16:
-		fastpathTV.EncMapIntfInt16V(*v, e)
+		fastpathTV.EncMapIntfInt16V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]int32:
-		fastpathTV.EncMapIntfInt32V(v, e)
+		fastpathTV.EncMapIntfInt32V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]int32:
-		fastpathTV.EncMapIntfInt32V(*v, e)
+		fastpathTV.EncMapIntfInt32V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]int64:
-		fastpathTV.EncMapIntfInt64V(v, e)
+		fastpathTV.EncMapIntfInt64V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]int64:
-		fastpathTV.EncMapIntfInt64V(*v, e)
+		fastpathTV.EncMapIntfInt64V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]float32:
-		fastpathTV.EncMapIntfFloat32V(v, e)
+		fastpathTV.EncMapIntfFloat32V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]float32:
-		fastpathTV.EncMapIntfFloat32V(*v, e)
+		fastpathTV.EncMapIntfFloat32V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]float64:
-		fastpathTV.EncMapIntfFloat64V(v, e)
+		fastpathTV.EncMapIntfFloat64V(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]float64:
-		fastpathTV.EncMapIntfFloat64V(*v, e)
+		fastpathTV.EncMapIntfFloat64V(*v, fastpathCheckNilTrue, e)
+
 	case map[interface{}]bool:
-		fastpathTV.EncMapIntfBoolV(v, e)
+		fastpathTV.EncMapIntfBoolV(v, fastpathCheckNilTrue, e)
 	case *map[interface{}]bool:
-		fastpathTV.EncMapIntfBoolV(*v, e)
+		fastpathTV.EncMapIntfBoolV(*v, fastpathCheckNilTrue, e)
+
+	case []string:
+		fastpathTV.EncSliceStringV(v, fastpathCheckNilTrue, e)
+	case *[]string:
+		fastpathTV.EncSliceStringV(*v, fastpathCheckNilTrue, e)
+
 	case map[string]interface{}:
-		fastpathTV.EncMapStringIntfV(v, e)
+		fastpathTV.EncMapStringIntfV(v, fastpathCheckNilTrue, e)
 	case *map[string]interface{}:
-		fastpathTV.EncMapStringIntfV(*v, e)
+		fastpathTV.EncMapStringIntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[string]string:
-		fastpathTV.EncMapStringStringV(v, e)
+		fastpathTV.EncMapStringStringV(v, fastpathCheckNilTrue, e)
 	case *map[string]string:
-		fastpathTV.EncMapStringStringV(*v, e)
+		fastpathTV.EncMapStringStringV(*v, fastpathCheckNilTrue, e)
+
 	case map[string]uint:
-		fastpathTV.EncMapStringUintV(v, e)
+		fastpathTV.EncMapStringUintV(v, fastpathCheckNilTrue, e)
 	case *map[string]uint:
-		fastpathTV.EncMapStringUintV(*v, e)
+		fastpathTV.EncMapStringUintV(*v, fastpathCheckNilTrue, e)
+
 	case map[string]uint8:
-		fastpathTV.EncMapStringUint8V(v, e)
+		fastpathTV.EncMapStringUint8V(v, fastpathCheckNilTrue, e)
 	case *map[string]uint8:
-		fastpathTV.EncMapStringUint8V(*v, e)
+		fastpathTV.EncMapStringUint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]uint16:
-		fastpathTV.EncMapStringUint16V(v, e)
+		fastpathTV.EncMapStringUint16V(v, fastpathCheckNilTrue, e)
 	case *map[string]uint16:
-		fastpathTV.EncMapStringUint16V(*v, e)
+		fastpathTV.EncMapStringUint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]uint32:
-		fastpathTV.EncMapStringUint32V(v, e)
+		fastpathTV.EncMapStringUint32V(v, fastpathCheckNilTrue, e)
 	case *map[string]uint32:
-		fastpathTV.EncMapStringUint32V(*v, e)
+		fastpathTV.EncMapStringUint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]uint64:
-		fastpathTV.EncMapStringUint64V(v, e)
+		fastpathTV.EncMapStringUint64V(v, fastpathCheckNilTrue, e)
 	case *map[string]uint64:
-		fastpathTV.EncMapStringUint64V(*v, e)
+		fastpathTV.EncMapStringUint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]uintptr:
-		fastpathTV.EncMapStringUintptrV(v, e)
+		fastpathTV.EncMapStringUintptrV(v, fastpathCheckNilTrue, e)
 	case *map[string]uintptr:
-		fastpathTV.EncMapStringUintptrV(*v, e)
+		fastpathTV.EncMapStringUintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[string]int:
-		fastpathTV.EncMapStringIntV(v, e)
+		fastpathTV.EncMapStringIntV(v, fastpathCheckNilTrue, e)
 	case *map[string]int:
-		fastpathTV.EncMapStringIntV(*v, e)
+		fastpathTV.EncMapStringIntV(*v, fastpathCheckNilTrue, e)
+
 	case map[string]int8:
-		fastpathTV.EncMapStringInt8V(v, e)
+		fastpathTV.EncMapStringInt8V(v, fastpathCheckNilTrue, e)
 	case *map[string]int8:
-		fastpathTV.EncMapStringInt8V(*v, e)
+		fastpathTV.EncMapStringInt8V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]int16:
-		fastpathTV.EncMapStringInt16V(v, e)
+		fastpathTV.EncMapStringInt16V(v, fastpathCheckNilTrue, e)
 	case *map[string]int16:
-		fastpathTV.EncMapStringInt16V(*v, e)
+		fastpathTV.EncMapStringInt16V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]int32:
-		fastpathTV.EncMapStringInt32V(v, e)
+		fastpathTV.EncMapStringInt32V(v, fastpathCheckNilTrue, e)
 	case *map[string]int32:
-		fastpathTV.EncMapStringInt32V(*v, e)
+		fastpathTV.EncMapStringInt32V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]int64:
-		fastpathTV.EncMapStringInt64V(v, e)
+		fastpathTV.EncMapStringInt64V(v, fastpathCheckNilTrue, e)
 	case *map[string]int64:
-		fastpathTV.EncMapStringInt64V(*v, e)
+		fastpathTV.EncMapStringInt64V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]float32:
-		fastpathTV.EncMapStringFloat32V(v, e)
+		fastpathTV.EncMapStringFloat32V(v, fastpathCheckNilTrue, e)
 	case *map[string]float32:
-		fastpathTV.EncMapStringFloat32V(*v, e)
+		fastpathTV.EncMapStringFloat32V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]float64:
-		fastpathTV.EncMapStringFloat64V(v, e)
+		fastpathTV.EncMapStringFloat64V(v, fastpathCheckNilTrue, e)
 	case *map[string]float64:
-		fastpathTV.EncMapStringFloat64V(*v, e)
+		fastpathTV.EncMapStringFloat64V(*v, fastpathCheckNilTrue, e)
+
 	case map[string]bool:
-		fastpathTV.EncMapStringBoolV(v, e)
+		fastpathTV.EncMapStringBoolV(v, fastpathCheckNilTrue, e)
 	case *map[string]bool:
-		fastpathTV.EncMapStringBoolV(*v, e)
+		fastpathTV.EncMapStringBoolV(*v, fastpathCheckNilTrue, e)
+
+	case []float32:
+		fastpathTV.EncSliceFloat32V(v, fastpathCheckNilTrue, e)
+	case *[]float32:
+		fastpathTV.EncSliceFloat32V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]interface{}:
-		fastpathTV.EncMapFloat32IntfV(v, e)
+		fastpathTV.EncMapFloat32IntfV(v, fastpathCheckNilTrue, e)
 	case *map[float32]interface{}:
-		fastpathTV.EncMapFloat32IntfV(*v, e)
+		fastpathTV.EncMapFloat32IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]string:
-		fastpathTV.EncMapFloat32StringV(v, e)
+		fastpathTV.EncMapFloat32StringV(v, fastpathCheckNilTrue, e)
 	case *map[float32]string:
-		fastpathTV.EncMapFloat32StringV(*v, e)
+		fastpathTV.EncMapFloat32StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]uint:
-		fastpathTV.EncMapFloat32UintV(v, e)
+		fastpathTV.EncMapFloat32UintV(v, fastpathCheckNilTrue, e)
 	case *map[float32]uint:
-		fastpathTV.EncMapFloat32UintV(*v, e)
+		fastpathTV.EncMapFloat32UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]uint8:
-		fastpathTV.EncMapFloat32Uint8V(v, e)
+		fastpathTV.EncMapFloat32Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[float32]uint8:
-		fastpathTV.EncMapFloat32Uint8V(*v, e)
+		fastpathTV.EncMapFloat32Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]uint16:
-		fastpathTV.EncMapFloat32Uint16V(v, e)
+		fastpathTV.EncMapFloat32Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[float32]uint16:
-		fastpathTV.EncMapFloat32Uint16V(*v, e)
+		fastpathTV.EncMapFloat32Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]uint32:
-		fastpathTV.EncMapFloat32Uint32V(v, e)
+		fastpathTV.EncMapFloat32Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[float32]uint32:
-		fastpathTV.EncMapFloat32Uint32V(*v, e)
+		fastpathTV.EncMapFloat32Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]uint64:
-		fastpathTV.EncMapFloat32Uint64V(v, e)
+		fastpathTV.EncMapFloat32Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[float32]uint64:
-		fastpathTV.EncMapFloat32Uint64V(*v, e)
+		fastpathTV.EncMapFloat32Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]uintptr:
-		fastpathTV.EncMapFloat32UintptrV(v, e)
+		fastpathTV.EncMapFloat32UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[float32]uintptr:
-		fastpathTV.EncMapFloat32UintptrV(*v, e)
+		fastpathTV.EncMapFloat32UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]int:
-		fastpathTV.EncMapFloat32IntV(v, e)
+		fastpathTV.EncMapFloat32IntV(v, fastpathCheckNilTrue, e)
 	case *map[float32]int:
-		fastpathTV.EncMapFloat32IntV(*v, e)
+		fastpathTV.EncMapFloat32IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]int8:
-		fastpathTV.EncMapFloat32Int8V(v, e)
+		fastpathTV.EncMapFloat32Int8V(v, fastpathCheckNilTrue, e)
 	case *map[float32]int8:
-		fastpathTV.EncMapFloat32Int8V(*v, e)
+		fastpathTV.EncMapFloat32Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]int16:
-		fastpathTV.EncMapFloat32Int16V(v, e)
+		fastpathTV.EncMapFloat32Int16V(v, fastpathCheckNilTrue, e)
 	case *map[float32]int16:
-		fastpathTV.EncMapFloat32Int16V(*v, e)
+		fastpathTV.EncMapFloat32Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]int32:
-		fastpathTV.EncMapFloat32Int32V(v, e)
+		fastpathTV.EncMapFloat32Int32V(v, fastpathCheckNilTrue, e)
 	case *map[float32]int32:
-		fastpathTV.EncMapFloat32Int32V(*v, e)
+		fastpathTV.EncMapFloat32Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]int64:
-		fastpathTV.EncMapFloat32Int64V(v, e)
+		fastpathTV.EncMapFloat32Int64V(v, fastpathCheckNilTrue, e)
 	case *map[float32]int64:
-		fastpathTV.EncMapFloat32Int64V(*v, e)
+		fastpathTV.EncMapFloat32Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]float32:
-		fastpathTV.EncMapFloat32Float32V(v, e)
+		fastpathTV.EncMapFloat32Float32V(v, fastpathCheckNilTrue, e)
 	case *map[float32]float32:
-		fastpathTV.EncMapFloat32Float32V(*v, e)
+		fastpathTV.EncMapFloat32Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]float64:
-		fastpathTV.EncMapFloat32Float64V(v, e)
+		fastpathTV.EncMapFloat32Float64V(v, fastpathCheckNilTrue, e)
 	case *map[float32]float64:
-		fastpathTV.EncMapFloat32Float64V(*v, e)
+		fastpathTV.EncMapFloat32Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[float32]bool:
-		fastpathTV.EncMapFloat32BoolV(v, e)
+		fastpathTV.EncMapFloat32BoolV(v, fastpathCheckNilTrue, e)
 	case *map[float32]bool:
-		fastpathTV.EncMapFloat32BoolV(*v, e)
+		fastpathTV.EncMapFloat32BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []float64:
+		fastpathTV.EncSliceFloat64V(v, fastpathCheckNilTrue, e)
+	case *[]float64:
+		fastpathTV.EncSliceFloat64V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]interface{}:
-		fastpathTV.EncMapFloat64IntfV(v, e)
+		fastpathTV.EncMapFloat64IntfV(v, fastpathCheckNilTrue, e)
 	case *map[float64]interface{}:
-		fastpathTV.EncMapFloat64IntfV(*v, e)
+		fastpathTV.EncMapFloat64IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]string:
-		fastpathTV.EncMapFloat64StringV(v, e)
+		fastpathTV.EncMapFloat64StringV(v, fastpathCheckNilTrue, e)
 	case *map[float64]string:
-		fastpathTV.EncMapFloat64StringV(*v, e)
+		fastpathTV.EncMapFloat64StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]uint:
-		fastpathTV.EncMapFloat64UintV(v, e)
+		fastpathTV.EncMapFloat64UintV(v, fastpathCheckNilTrue, e)
 	case *map[float64]uint:
-		fastpathTV.EncMapFloat64UintV(*v, e)
+		fastpathTV.EncMapFloat64UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]uint8:
-		fastpathTV.EncMapFloat64Uint8V(v, e)
+		fastpathTV.EncMapFloat64Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[float64]uint8:
-		fastpathTV.EncMapFloat64Uint8V(*v, e)
+		fastpathTV.EncMapFloat64Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]uint16:
-		fastpathTV.EncMapFloat64Uint16V(v, e)
+		fastpathTV.EncMapFloat64Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[float64]uint16:
-		fastpathTV.EncMapFloat64Uint16V(*v, e)
+		fastpathTV.EncMapFloat64Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]uint32:
-		fastpathTV.EncMapFloat64Uint32V(v, e)
+		fastpathTV.EncMapFloat64Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[float64]uint32:
-		fastpathTV.EncMapFloat64Uint32V(*v, e)
+		fastpathTV.EncMapFloat64Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]uint64:
-		fastpathTV.EncMapFloat64Uint64V(v, e)
+		fastpathTV.EncMapFloat64Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[float64]uint64:
-		fastpathTV.EncMapFloat64Uint64V(*v, e)
+		fastpathTV.EncMapFloat64Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]uintptr:
-		fastpathTV.EncMapFloat64UintptrV(v, e)
+		fastpathTV.EncMapFloat64UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[float64]uintptr:
-		fastpathTV.EncMapFloat64UintptrV(*v, e)
+		fastpathTV.EncMapFloat64UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]int:
-		fastpathTV.EncMapFloat64IntV(v, e)
+		fastpathTV.EncMapFloat64IntV(v, fastpathCheckNilTrue, e)
 	case *map[float64]int:
-		fastpathTV.EncMapFloat64IntV(*v, e)
+		fastpathTV.EncMapFloat64IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]int8:
-		fastpathTV.EncMapFloat64Int8V(v, e)
+		fastpathTV.EncMapFloat64Int8V(v, fastpathCheckNilTrue, e)
 	case *map[float64]int8:
-		fastpathTV.EncMapFloat64Int8V(*v, e)
+		fastpathTV.EncMapFloat64Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]int16:
-		fastpathTV.EncMapFloat64Int16V(v, e)
+		fastpathTV.EncMapFloat64Int16V(v, fastpathCheckNilTrue, e)
 	case *map[float64]int16:
-		fastpathTV.EncMapFloat64Int16V(*v, e)
+		fastpathTV.EncMapFloat64Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]int32:
-		fastpathTV.EncMapFloat64Int32V(v, e)
+		fastpathTV.EncMapFloat64Int32V(v, fastpathCheckNilTrue, e)
 	case *map[float64]int32:
-		fastpathTV.EncMapFloat64Int32V(*v, e)
+		fastpathTV.EncMapFloat64Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]int64:
-		fastpathTV.EncMapFloat64Int64V(v, e)
+		fastpathTV.EncMapFloat64Int64V(v, fastpathCheckNilTrue, e)
 	case *map[float64]int64:
-		fastpathTV.EncMapFloat64Int64V(*v, e)
+		fastpathTV.EncMapFloat64Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]float32:
-		fastpathTV.EncMapFloat64Float32V(v, e)
+		fastpathTV.EncMapFloat64Float32V(v, fastpathCheckNilTrue, e)
 	case *map[float64]float32:
-		fastpathTV.EncMapFloat64Float32V(*v, e)
+		fastpathTV.EncMapFloat64Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]float64:
-		fastpathTV.EncMapFloat64Float64V(v, e)
+		fastpathTV.EncMapFloat64Float64V(v, fastpathCheckNilTrue, e)
 	case *map[float64]float64:
-		fastpathTV.EncMapFloat64Float64V(*v, e)
+		fastpathTV.EncMapFloat64Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[float64]bool:
-		fastpathTV.EncMapFloat64BoolV(v, e)
+		fastpathTV.EncMapFloat64BoolV(v, fastpathCheckNilTrue, e)
 	case *map[float64]bool:
-		fastpathTV.EncMapFloat64BoolV(*v, e)
+		fastpathTV.EncMapFloat64BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []uint:
+		fastpathTV.EncSliceUintV(v, fastpathCheckNilTrue, e)
+	case *[]uint:
+		fastpathTV.EncSliceUintV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]interface{}:
-		fastpathTV.EncMapUintIntfV(v, e)
+		fastpathTV.EncMapUintIntfV(v, fastpathCheckNilTrue, e)
 	case *map[uint]interface{}:
-		fastpathTV.EncMapUintIntfV(*v, e)
+		fastpathTV.EncMapUintIntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]string:
-		fastpathTV.EncMapUintStringV(v, e)
+		fastpathTV.EncMapUintStringV(v, fastpathCheckNilTrue, e)
 	case *map[uint]string:
-		fastpathTV.EncMapUintStringV(*v, e)
+		fastpathTV.EncMapUintStringV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]uint:
-		fastpathTV.EncMapUintUintV(v, e)
+		fastpathTV.EncMapUintUintV(v, fastpathCheckNilTrue, e)
 	case *map[uint]uint:
-		fastpathTV.EncMapUintUintV(*v, e)
+		fastpathTV.EncMapUintUintV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]uint8:
-		fastpathTV.EncMapUintUint8V(v, e)
+		fastpathTV.EncMapUintUint8V(v, fastpathCheckNilTrue, e)
 	case *map[uint]uint8:
-		fastpathTV.EncMapUintUint8V(*v, e)
+		fastpathTV.EncMapUintUint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]uint16:
-		fastpathTV.EncMapUintUint16V(v, e)
+		fastpathTV.EncMapUintUint16V(v, fastpathCheckNilTrue, e)
 	case *map[uint]uint16:
-		fastpathTV.EncMapUintUint16V(*v, e)
+		fastpathTV.EncMapUintUint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]uint32:
-		fastpathTV.EncMapUintUint32V(v, e)
+		fastpathTV.EncMapUintUint32V(v, fastpathCheckNilTrue, e)
 	case *map[uint]uint32:
-		fastpathTV.EncMapUintUint32V(*v, e)
+		fastpathTV.EncMapUintUint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]uint64:
-		fastpathTV.EncMapUintUint64V(v, e)
+		fastpathTV.EncMapUintUint64V(v, fastpathCheckNilTrue, e)
 	case *map[uint]uint64:
-		fastpathTV.EncMapUintUint64V(*v, e)
+		fastpathTV.EncMapUintUint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]uintptr:
-		fastpathTV.EncMapUintUintptrV(v, e)
+		fastpathTV.EncMapUintUintptrV(v, fastpathCheckNilTrue, e)
 	case *map[uint]uintptr:
-		fastpathTV.EncMapUintUintptrV(*v, e)
+		fastpathTV.EncMapUintUintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]int:
-		fastpathTV.EncMapUintIntV(v, e)
+		fastpathTV.EncMapUintIntV(v, fastpathCheckNilTrue, e)
 	case *map[uint]int:
-		fastpathTV.EncMapUintIntV(*v, e)
+		fastpathTV.EncMapUintIntV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]int8:
-		fastpathTV.EncMapUintInt8V(v, e)
+		fastpathTV.EncMapUintInt8V(v, fastpathCheckNilTrue, e)
 	case *map[uint]int8:
-		fastpathTV.EncMapUintInt8V(*v, e)
+		fastpathTV.EncMapUintInt8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]int16:
-		fastpathTV.EncMapUintInt16V(v, e)
+		fastpathTV.EncMapUintInt16V(v, fastpathCheckNilTrue, e)
 	case *map[uint]int16:
-		fastpathTV.EncMapUintInt16V(*v, e)
+		fastpathTV.EncMapUintInt16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]int32:
-		fastpathTV.EncMapUintInt32V(v, e)
+		fastpathTV.EncMapUintInt32V(v, fastpathCheckNilTrue, e)
 	case *map[uint]int32:
-		fastpathTV.EncMapUintInt32V(*v, e)
+		fastpathTV.EncMapUintInt32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]int64:
-		fastpathTV.EncMapUintInt64V(v, e)
+		fastpathTV.EncMapUintInt64V(v, fastpathCheckNilTrue, e)
 	case *map[uint]int64:
-		fastpathTV.EncMapUintInt64V(*v, e)
+		fastpathTV.EncMapUintInt64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]float32:
-		fastpathTV.EncMapUintFloat32V(v, e)
+		fastpathTV.EncMapUintFloat32V(v, fastpathCheckNilTrue, e)
 	case *map[uint]float32:
-		fastpathTV.EncMapUintFloat32V(*v, e)
+		fastpathTV.EncMapUintFloat32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]float64:
-		fastpathTV.EncMapUintFloat64V(v, e)
+		fastpathTV.EncMapUintFloat64V(v, fastpathCheckNilTrue, e)
 	case *map[uint]float64:
-		fastpathTV.EncMapUintFloat64V(*v, e)
+		fastpathTV.EncMapUintFloat64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint]bool:
-		fastpathTV.EncMapUintBoolV(v, e)
+		fastpathTV.EncMapUintBoolV(v, fastpathCheckNilTrue, e)
 	case *map[uint]bool:
-		fastpathTV.EncMapUintBoolV(*v, e)
+		fastpathTV.EncMapUintBoolV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]interface{}:
-		fastpathTV.EncMapUint8IntfV(v, e)
+		fastpathTV.EncMapUint8IntfV(v, fastpathCheckNilTrue, e)
 	case *map[uint8]interface{}:
-		fastpathTV.EncMapUint8IntfV(*v, e)
+		fastpathTV.EncMapUint8IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]string:
-		fastpathTV.EncMapUint8StringV(v, e)
+		fastpathTV.EncMapUint8StringV(v, fastpathCheckNilTrue, e)
 	case *map[uint8]string:
-		fastpathTV.EncMapUint8StringV(*v, e)
+		fastpathTV.EncMapUint8StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]uint:
-		fastpathTV.EncMapUint8UintV(v, e)
+		fastpathTV.EncMapUint8UintV(v, fastpathCheckNilTrue, e)
 	case *map[uint8]uint:
-		fastpathTV.EncMapUint8UintV(*v, e)
+		fastpathTV.EncMapUint8UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]uint8:
-		fastpathTV.EncMapUint8Uint8V(v, e)
+		fastpathTV.EncMapUint8Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]uint8:
-		fastpathTV.EncMapUint8Uint8V(*v, e)
+		fastpathTV.EncMapUint8Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]uint16:
-		fastpathTV.EncMapUint8Uint16V(v, e)
+		fastpathTV.EncMapUint8Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]uint16:
-		fastpathTV.EncMapUint8Uint16V(*v, e)
+		fastpathTV.EncMapUint8Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]uint32:
-		fastpathTV.EncMapUint8Uint32V(v, e)
+		fastpathTV.EncMapUint8Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]uint32:
-		fastpathTV.EncMapUint8Uint32V(*v, e)
+		fastpathTV.EncMapUint8Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]uint64:
-		fastpathTV.EncMapUint8Uint64V(v, e)
+		fastpathTV.EncMapUint8Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]uint64:
-		fastpathTV.EncMapUint8Uint64V(*v, e)
+		fastpathTV.EncMapUint8Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]uintptr:
-		fastpathTV.EncMapUint8UintptrV(v, e)
+		fastpathTV.EncMapUint8UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[uint8]uintptr:
-		fastpathTV.EncMapUint8UintptrV(*v, e)
+		fastpathTV.EncMapUint8UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]int:
-		fastpathTV.EncMapUint8IntV(v, e)
+		fastpathTV.EncMapUint8IntV(v, fastpathCheckNilTrue, e)
 	case *map[uint8]int:
-		fastpathTV.EncMapUint8IntV(*v, e)
+		fastpathTV.EncMapUint8IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]int8:
-		fastpathTV.EncMapUint8Int8V(v, e)
+		fastpathTV.EncMapUint8Int8V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]int8:
-		fastpathTV.EncMapUint8Int8V(*v, e)
+		fastpathTV.EncMapUint8Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]int16:
-		fastpathTV.EncMapUint8Int16V(v, e)
+		fastpathTV.EncMapUint8Int16V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]int16:
-		fastpathTV.EncMapUint8Int16V(*v, e)
+		fastpathTV.EncMapUint8Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]int32:
-		fastpathTV.EncMapUint8Int32V(v, e)
+		fastpathTV.EncMapUint8Int32V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]int32:
-		fastpathTV.EncMapUint8Int32V(*v, e)
+		fastpathTV.EncMapUint8Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]int64:
-		fastpathTV.EncMapUint8Int64V(v, e)
+		fastpathTV.EncMapUint8Int64V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]int64:
-		fastpathTV.EncMapUint8Int64V(*v, e)
+		fastpathTV.EncMapUint8Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]float32:
-		fastpathTV.EncMapUint8Float32V(v, e)
+		fastpathTV.EncMapUint8Float32V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]float32:
-		fastpathTV.EncMapUint8Float32V(*v, e)
+		fastpathTV.EncMapUint8Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]float64:
-		fastpathTV.EncMapUint8Float64V(v, e)
+		fastpathTV.EncMapUint8Float64V(v, fastpathCheckNilTrue, e)
 	case *map[uint8]float64:
-		fastpathTV.EncMapUint8Float64V(*v, e)
+		fastpathTV.EncMapUint8Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint8]bool:
-		fastpathTV.EncMapUint8BoolV(v, e)
+		fastpathTV.EncMapUint8BoolV(v, fastpathCheckNilTrue, e)
 	case *map[uint8]bool:
-		fastpathTV.EncMapUint8BoolV(*v, e)
+		fastpathTV.EncMapUint8BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []uint16:
+		fastpathTV.EncSliceUint16V(v, fastpathCheckNilTrue, e)
+	case *[]uint16:
+		fastpathTV.EncSliceUint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]interface{}:
-		fastpathTV.EncMapUint16IntfV(v, e)
+		fastpathTV.EncMapUint16IntfV(v, fastpathCheckNilTrue, e)
 	case *map[uint16]interface{}:
-		fastpathTV.EncMapUint16IntfV(*v, e)
+		fastpathTV.EncMapUint16IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]string:
-		fastpathTV.EncMapUint16StringV(v, e)
+		fastpathTV.EncMapUint16StringV(v, fastpathCheckNilTrue, e)
 	case *map[uint16]string:
-		fastpathTV.EncMapUint16StringV(*v, e)
+		fastpathTV.EncMapUint16StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]uint:
-		fastpathTV.EncMapUint16UintV(v, e)
+		fastpathTV.EncMapUint16UintV(v, fastpathCheckNilTrue, e)
 	case *map[uint16]uint:
-		fastpathTV.EncMapUint16UintV(*v, e)
+		fastpathTV.EncMapUint16UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]uint8:
-		fastpathTV.EncMapUint16Uint8V(v, e)
+		fastpathTV.EncMapUint16Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]uint8:
-		fastpathTV.EncMapUint16Uint8V(*v, e)
+		fastpathTV.EncMapUint16Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]uint16:
-		fastpathTV.EncMapUint16Uint16V(v, e)
+		fastpathTV.EncMapUint16Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]uint16:
-		fastpathTV.EncMapUint16Uint16V(*v, e)
+		fastpathTV.EncMapUint16Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]uint32:
-		fastpathTV.EncMapUint16Uint32V(v, e)
+		fastpathTV.EncMapUint16Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]uint32:
-		fastpathTV.EncMapUint16Uint32V(*v, e)
+		fastpathTV.EncMapUint16Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]uint64:
-		fastpathTV.EncMapUint16Uint64V(v, e)
+		fastpathTV.EncMapUint16Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]uint64:
-		fastpathTV.EncMapUint16Uint64V(*v, e)
+		fastpathTV.EncMapUint16Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]uintptr:
-		fastpathTV.EncMapUint16UintptrV(v, e)
+		fastpathTV.EncMapUint16UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[uint16]uintptr:
-		fastpathTV.EncMapUint16UintptrV(*v, e)
+		fastpathTV.EncMapUint16UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]int:
-		fastpathTV.EncMapUint16IntV(v, e)
+		fastpathTV.EncMapUint16IntV(v, fastpathCheckNilTrue, e)
 	case *map[uint16]int:
-		fastpathTV.EncMapUint16IntV(*v, e)
+		fastpathTV.EncMapUint16IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]int8:
-		fastpathTV.EncMapUint16Int8V(v, e)
+		fastpathTV.EncMapUint16Int8V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]int8:
-		fastpathTV.EncMapUint16Int8V(*v, e)
+		fastpathTV.EncMapUint16Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]int16:
-		fastpathTV.EncMapUint16Int16V(v, e)
+		fastpathTV.EncMapUint16Int16V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]int16:
-		fastpathTV.EncMapUint16Int16V(*v, e)
+		fastpathTV.EncMapUint16Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]int32:
-		fastpathTV.EncMapUint16Int32V(v, e)
+		fastpathTV.EncMapUint16Int32V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]int32:
-		fastpathTV.EncMapUint16Int32V(*v, e)
+		fastpathTV.EncMapUint16Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]int64:
-		fastpathTV.EncMapUint16Int64V(v, e)
+		fastpathTV.EncMapUint16Int64V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]int64:
-		fastpathTV.EncMapUint16Int64V(*v, e)
+		fastpathTV.EncMapUint16Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]float32:
-		fastpathTV.EncMapUint16Float32V(v, e)
+		fastpathTV.EncMapUint16Float32V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]float32:
-		fastpathTV.EncMapUint16Float32V(*v, e)
+		fastpathTV.EncMapUint16Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]float64:
-		fastpathTV.EncMapUint16Float64V(v, e)
+		fastpathTV.EncMapUint16Float64V(v, fastpathCheckNilTrue, e)
 	case *map[uint16]float64:
-		fastpathTV.EncMapUint16Float64V(*v, e)
+		fastpathTV.EncMapUint16Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint16]bool:
-		fastpathTV.EncMapUint16BoolV(v, e)
+		fastpathTV.EncMapUint16BoolV(v, fastpathCheckNilTrue, e)
 	case *map[uint16]bool:
-		fastpathTV.EncMapUint16BoolV(*v, e)
+		fastpathTV.EncMapUint16BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []uint32:
+		fastpathTV.EncSliceUint32V(v, fastpathCheckNilTrue, e)
+	case *[]uint32:
+		fastpathTV.EncSliceUint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]interface{}:
-		fastpathTV.EncMapUint32IntfV(v, e)
+		fastpathTV.EncMapUint32IntfV(v, fastpathCheckNilTrue, e)
 	case *map[uint32]interface{}:
-		fastpathTV.EncMapUint32IntfV(*v, e)
+		fastpathTV.EncMapUint32IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]string:
-		fastpathTV.EncMapUint32StringV(v, e)
+		fastpathTV.EncMapUint32StringV(v, fastpathCheckNilTrue, e)
 	case *map[uint32]string:
-		fastpathTV.EncMapUint32StringV(*v, e)
+		fastpathTV.EncMapUint32StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]uint:
-		fastpathTV.EncMapUint32UintV(v, e)
+		fastpathTV.EncMapUint32UintV(v, fastpathCheckNilTrue, e)
 	case *map[uint32]uint:
-		fastpathTV.EncMapUint32UintV(*v, e)
+		fastpathTV.EncMapUint32UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]uint8:
-		fastpathTV.EncMapUint32Uint8V(v, e)
+		fastpathTV.EncMapUint32Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]uint8:
-		fastpathTV.EncMapUint32Uint8V(*v, e)
+		fastpathTV.EncMapUint32Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]uint16:
-		fastpathTV.EncMapUint32Uint16V(v, e)
+		fastpathTV.EncMapUint32Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]uint16:
-		fastpathTV.EncMapUint32Uint16V(*v, e)
+		fastpathTV.EncMapUint32Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]uint32:
-		fastpathTV.EncMapUint32Uint32V(v, e)
+		fastpathTV.EncMapUint32Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]uint32:
-		fastpathTV.EncMapUint32Uint32V(*v, e)
+		fastpathTV.EncMapUint32Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]uint64:
-		fastpathTV.EncMapUint32Uint64V(v, e)
+		fastpathTV.EncMapUint32Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]uint64:
-		fastpathTV.EncMapUint32Uint64V(*v, e)
+		fastpathTV.EncMapUint32Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]uintptr:
-		fastpathTV.EncMapUint32UintptrV(v, e)
+		fastpathTV.EncMapUint32UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[uint32]uintptr:
-		fastpathTV.EncMapUint32UintptrV(*v, e)
+		fastpathTV.EncMapUint32UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]int:
-		fastpathTV.EncMapUint32IntV(v, e)
+		fastpathTV.EncMapUint32IntV(v, fastpathCheckNilTrue, e)
 	case *map[uint32]int:
-		fastpathTV.EncMapUint32IntV(*v, e)
+		fastpathTV.EncMapUint32IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]int8:
-		fastpathTV.EncMapUint32Int8V(v, e)
+		fastpathTV.EncMapUint32Int8V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]int8:
-		fastpathTV.EncMapUint32Int8V(*v, e)
+		fastpathTV.EncMapUint32Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]int16:
-		fastpathTV.EncMapUint32Int16V(v, e)
+		fastpathTV.EncMapUint32Int16V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]int16:
-		fastpathTV.EncMapUint32Int16V(*v, e)
+		fastpathTV.EncMapUint32Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]int32:
-		fastpathTV.EncMapUint32Int32V(v, e)
+		fastpathTV.EncMapUint32Int32V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]int32:
-		fastpathTV.EncMapUint32Int32V(*v, e)
+		fastpathTV.EncMapUint32Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]int64:
-		fastpathTV.EncMapUint32Int64V(v, e)
+		fastpathTV.EncMapUint32Int64V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]int64:
-		fastpathTV.EncMapUint32Int64V(*v, e)
+		fastpathTV.EncMapUint32Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]float32:
-		fastpathTV.EncMapUint32Float32V(v, e)
+		fastpathTV.EncMapUint32Float32V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]float32:
-		fastpathTV.EncMapUint32Float32V(*v, e)
+		fastpathTV.EncMapUint32Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]float64:
-		fastpathTV.EncMapUint32Float64V(v, e)
+		fastpathTV.EncMapUint32Float64V(v, fastpathCheckNilTrue, e)
 	case *map[uint32]float64:
-		fastpathTV.EncMapUint32Float64V(*v, e)
+		fastpathTV.EncMapUint32Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint32]bool:
-		fastpathTV.EncMapUint32BoolV(v, e)
+		fastpathTV.EncMapUint32BoolV(v, fastpathCheckNilTrue, e)
 	case *map[uint32]bool:
-		fastpathTV.EncMapUint32BoolV(*v, e)
+		fastpathTV.EncMapUint32BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []uint64:
+		fastpathTV.EncSliceUint64V(v, fastpathCheckNilTrue, e)
+	case *[]uint64:
+		fastpathTV.EncSliceUint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]interface{}:
-		fastpathTV.EncMapUint64IntfV(v, e)
+		fastpathTV.EncMapUint64IntfV(v, fastpathCheckNilTrue, e)
 	case *map[uint64]interface{}:
-		fastpathTV.EncMapUint64IntfV(*v, e)
+		fastpathTV.EncMapUint64IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]string:
-		fastpathTV.EncMapUint64StringV(v, e)
+		fastpathTV.EncMapUint64StringV(v, fastpathCheckNilTrue, e)
 	case *map[uint64]string:
-		fastpathTV.EncMapUint64StringV(*v, e)
+		fastpathTV.EncMapUint64StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]uint:
-		fastpathTV.EncMapUint64UintV(v, e)
+		fastpathTV.EncMapUint64UintV(v, fastpathCheckNilTrue, e)
 	case *map[uint64]uint:
-		fastpathTV.EncMapUint64UintV(*v, e)
+		fastpathTV.EncMapUint64UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]uint8:
-		fastpathTV.EncMapUint64Uint8V(v, e)
+		fastpathTV.EncMapUint64Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]uint8:
-		fastpathTV.EncMapUint64Uint8V(*v, e)
+		fastpathTV.EncMapUint64Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]uint16:
-		fastpathTV.EncMapUint64Uint16V(v, e)
+		fastpathTV.EncMapUint64Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]uint16:
-		fastpathTV.EncMapUint64Uint16V(*v, e)
+		fastpathTV.EncMapUint64Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]uint32:
-		fastpathTV.EncMapUint64Uint32V(v, e)
+		fastpathTV.EncMapUint64Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]uint32:
-		fastpathTV.EncMapUint64Uint32V(*v, e)
+		fastpathTV.EncMapUint64Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]uint64:
-		fastpathTV.EncMapUint64Uint64V(v, e)
+		fastpathTV.EncMapUint64Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]uint64:
-		fastpathTV.EncMapUint64Uint64V(*v, e)
+		fastpathTV.EncMapUint64Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]uintptr:
-		fastpathTV.EncMapUint64UintptrV(v, e)
+		fastpathTV.EncMapUint64UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[uint64]uintptr:
-		fastpathTV.EncMapUint64UintptrV(*v, e)
+		fastpathTV.EncMapUint64UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]int:
-		fastpathTV.EncMapUint64IntV(v, e)
+		fastpathTV.EncMapUint64IntV(v, fastpathCheckNilTrue, e)
 	case *map[uint64]int:
-		fastpathTV.EncMapUint64IntV(*v, e)
+		fastpathTV.EncMapUint64IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]int8:
-		fastpathTV.EncMapUint64Int8V(v, e)
+		fastpathTV.EncMapUint64Int8V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]int8:
-		fastpathTV.EncMapUint64Int8V(*v, e)
+		fastpathTV.EncMapUint64Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]int16:
-		fastpathTV.EncMapUint64Int16V(v, e)
+		fastpathTV.EncMapUint64Int16V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]int16:
-		fastpathTV.EncMapUint64Int16V(*v, e)
+		fastpathTV.EncMapUint64Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]int32:
-		fastpathTV.EncMapUint64Int32V(v, e)
+		fastpathTV.EncMapUint64Int32V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]int32:
-		fastpathTV.EncMapUint64Int32V(*v, e)
+		fastpathTV.EncMapUint64Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]int64:
-		fastpathTV.EncMapUint64Int64V(v, e)
+		fastpathTV.EncMapUint64Int64V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]int64:
-		fastpathTV.EncMapUint64Int64V(*v, e)
+		fastpathTV.EncMapUint64Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]float32:
-		fastpathTV.EncMapUint64Float32V(v, e)
+		fastpathTV.EncMapUint64Float32V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]float32:
-		fastpathTV.EncMapUint64Float32V(*v, e)
+		fastpathTV.EncMapUint64Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]float64:
-		fastpathTV.EncMapUint64Float64V(v, e)
+		fastpathTV.EncMapUint64Float64V(v, fastpathCheckNilTrue, e)
 	case *map[uint64]float64:
-		fastpathTV.EncMapUint64Float64V(*v, e)
+		fastpathTV.EncMapUint64Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uint64]bool:
-		fastpathTV.EncMapUint64BoolV(v, e)
+		fastpathTV.EncMapUint64BoolV(v, fastpathCheckNilTrue, e)
 	case *map[uint64]bool:
-		fastpathTV.EncMapUint64BoolV(*v, e)
+		fastpathTV.EncMapUint64BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []uintptr:
+		fastpathTV.EncSliceUintptrV(v, fastpathCheckNilTrue, e)
+	case *[]uintptr:
+		fastpathTV.EncSliceUintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]interface{}:
-		fastpathTV.EncMapUintptrIntfV(v, e)
+		fastpathTV.EncMapUintptrIntfV(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]interface{}:
-		fastpathTV.EncMapUintptrIntfV(*v, e)
+		fastpathTV.EncMapUintptrIntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]string:
-		fastpathTV.EncMapUintptrStringV(v, e)
+		fastpathTV.EncMapUintptrStringV(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]string:
-		fastpathTV.EncMapUintptrStringV(*v, e)
+		fastpathTV.EncMapUintptrStringV(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]uint:
-		fastpathTV.EncMapUintptrUintV(v, e)
+		fastpathTV.EncMapUintptrUintV(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]uint:
-		fastpathTV.EncMapUintptrUintV(*v, e)
+		fastpathTV.EncMapUintptrUintV(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]uint8:
-		fastpathTV.EncMapUintptrUint8V(v, e)
+		fastpathTV.EncMapUintptrUint8V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]uint8:
-		fastpathTV.EncMapUintptrUint8V(*v, e)
+		fastpathTV.EncMapUintptrUint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]uint16:
-		fastpathTV.EncMapUintptrUint16V(v, e)
+		fastpathTV.EncMapUintptrUint16V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]uint16:
-		fastpathTV.EncMapUintptrUint16V(*v, e)
+		fastpathTV.EncMapUintptrUint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]uint32:
-		fastpathTV.EncMapUintptrUint32V(v, e)
+		fastpathTV.EncMapUintptrUint32V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]uint32:
-		fastpathTV.EncMapUintptrUint32V(*v, e)
+		fastpathTV.EncMapUintptrUint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]uint64:
-		fastpathTV.EncMapUintptrUint64V(v, e)
+		fastpathTV.EncMapUintptrUint64V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]uint64:
-		fastpathTV.EncMapUintptrUint64V(*v, e)
+		fastpathTV.EncMapUintptrUint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]uintptr:
-		fastpathTV.EncMapUintptrUintptrV(v, e)
+		fastpathTV.EncMapUintptrUintptrV(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]uintptr:
-		fastpathTV.EncMapUintptrUintptrV(*v, e)
+		fastpathTV.EncMapUintptrUintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]int:
-		fastpathTV.EncMapUintptrIntV(v, e)
+		fastpathTV.EncMapUintptrIntV(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]int:
-		fastpathTV.EncMapUintptrIntV(*v, e)
+		fastpathTV.EncMapUintptrIntV(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]int8:
-		fastpathTV.EncMapUintptrInt8V(v, e)
+		fastpathTV.EncMapUintptrInt8V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]int8:
-		fastpathTV.EncMapUintptrInt8V(*v, e)
+		fastpathTV.EncMapUintptrInt8V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]int16:
-		fastpathTV.EncMapUintptrInt16V(v, e)
+		fastpathTV.EncMapUintptrInt16V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]int16:
-		fastpathTV.EncMapUintptrInt16V(*v, e)
+		fastpathTV.EncMapUintptrInt16V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]int32:
-		fastpathTV.EncMapUintptrInt32V(v, e)
+		fastpathTV.EncMapUintptrInt32V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]int32:
-		fastpathTV.EncMapUintptrInt32V(*v, e)
+		fastpathTV.EncMapUintptrInt32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]int64:
-		fastpathTV.EncMapUintptrInt64V(v, e)
+		fastpathTV.EncMapUintptrInt64V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]int64:
-		fastpathTV.EncMapUintptrInt64V(*v, e)
+		fastpathTV.EncMapUintptrInt64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]float32:
-		fastpathTV.EncMapUintptrFloat32V(v, e)
+		fastpathTV.EncMapUintptrFloat32V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]float32:
-		fastpathTV.EncMapUintptrFloat32V(*v, e)
+		fastpathTV.EncMapUintptrFloat32V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]float64:
-		fastpathTV.EncMapUintptrFloat64V(v, e)
+		fastpathTV.EncMapUintptrFloat64V(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]float64:
-		fastpathTV.EncMapUintptrFloat64V(*v, e)
+		fastpathTV.EncMapUintptrFloat64V(*v, fastpathCheckNilTrue, e)
+
 	case map[uintptr]bool:
-		fastpathTV.EncMapUintptrBoolV(v, e)
+		fastpathTV.EncMapUintptrBoolV(v, fastpathCheckNilTrue, e)
 	case *map[uintptr]bool:
-		fastpathTV.EncMapUintptrBoolV(*v, e)
+		fastpathTV.EncMapUintptrBoolV(*v, fastpathCheckNilTrue, e)
+
+	case []int:
+		fastpathTV.EncSliceIntV(v, fastpathCheckNilTrue, e)
+	case *[]int:
+		fastpathTV.EncSliceIntV(*v, fastpathCheckNilTrue, e)
+
 	case map[int]interface{}:
-		fastpathTV.EncMapIntIntfV(v, e)
+		fastpathTV.EncMapIntIntfV(v, fastpathCheckNilTrue, e)
 	case *map[int]interface{}:
-		fastpathTV.EncMapIntIntfV(*v, e)
+		fastpathTV.EncMapIntIntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[int]string:
-		fastpathTV.EncMapIntStringV(v, e)
+		fastpathTV.EncMapIntStringV(v, fastpathCheckNilTrue, e)
 	case *map[int]string:
-		fastpathTV.EncMapIntStringV(*v, e)
+		fastpathTV.EncMapIntStringV(*v, fastpathCheckNilTrue, e)
+
 	case map[int]uint:
-		fastpathTV.EncMapIntUintV(v, e)
+		fastpathTV.EncMapIntUintV(v, fastpathCheckNilTrue, e)
 	case *map[int]uint:
-		fastpathTV.EncMapIntUintV(*v, e)
+		fastpathTV.EncMapIntUintV(*v, fastpathCheckNilTrue, e)
+
 	case map[int]uint8:
-		fastpathTV.EncMapIntUint8V(v, e)
+		fastpathTV.EncMapIntUint8V(v, fastpathCheckNilTrue, e)
 	case *map[int]uint8:
-		fastpathTV.EncMapIntUint8V(*v, e)
+		fastpathTV.EncMapIntUint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]uint16:
-		fastpathTV.EncMapIntUint16V(v, e)
+		fastpathTV.EncMapIntUint16V(v, fastpathCheckNilTrue, e)
 	case *map[int]uint16:
-		fastpathTV.EncMapIntUint16V(*v, e)
+		fastpathTV.EncMapIntUint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]uint32:
-		fastpathTV.EncMapIntUint32V(v, e)
+		fastpathTV.EncMapIntUint32V(v, fastpathCheckNilTrue, e)
 	case *map[int]uint32:
-		fastpathTV.EncMapIntUint32V(*v, e)
+		fastpathTV.EncMapIntUint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]uint64:
-		fastpathTV.EncMapIntUint64V(v, e)
+		fastpathTV.EncMapIntUint64V(v, fastpathCheckNilTrue, e)
 	case *map[int]uint64:
-		fastpathTV.EncMapIntUint64V(*v, e)
+		fastpathTV.EncMapIntUint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]uintptr:
-		fastpathTV.EncMapIntUintptrV(v, e)
+		fastpathTV.EncMapIntUintptrV(v, fastpathCheckNilTrue, e)
 	case *map[int]uintptr:
-		fastpathTV.EncMapIntUintptrV(*v, e)
+		fastpathTV.EncMapIntUintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[int]int:
-		fastpathTV.EncMapIntIntV(v, e)
+		fastpathTV.EncMapIntIntV(v, fastpathCheckNilTrue, e)
 	case *map[int]int:
-		fastpathTV.EncMapIntIntV(*v, e)
+		fastpathTV.EncMapIntIntV(*v, fastpathCheckNilTrue, e)
+
 	case map[int]int8:
-		fastpathTV.EncMapIntInt8V(v, e)
+		fastpathTV.EncMapIntInt8V(v, fastpathCheckNilTrue, e)
 	case *map[int]int8:
-		fastpathTV.EncMapIntInt8V(*v, e)
+		fastpathTV.EncMapIntInt8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]int16:
-		fastpathTV.EncMapIntInt16V(v, e)
+		fastpathTV.EncMapIntInt16V(v, fastpathCheckNilTrue, e)
 	case *map[int]int16:
-		fastpathTV.EncMapIntInt16V(*v, e)
+		fastpathTV.EncMapIntInt16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]int32:
-		fastpathTV.EncMapIntInt32V(v, e)
+		fastpathTV.EncMapIntInt32V(v, fastpathCheckNilTrue, e)
 	case *map[int]int32:
-		fastpathTV.EncMapIntInt32V(*v, e)
+		fastpathTV.EncMapIntInt32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]int64:
-		fastpathTV.EncMapIntInt64V(v, e)
+		fastpathTV.EncMapIntInt64V(v, fastpathCheckNilTrue, e)
 	case *map[int]int64:
-		fastpathTV.EncMapIntInt64V(*v, e)
+		fastpathTV.EncMapIntInt64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]float32:
-		fastpathTV.EncMapIntFloat32V(v, e)
+		fastpathTV.EncMapIntFloat32V(v, fastpathCheckNilTrue, e)
 	case *map[int]float32:
-		fastpathTV.EncMapIntFloat32V(*v, e)
+		fastpathTV.EncMapIntFloat32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]float64:
-		fastpathTV.EncMapIntFloat64V(v, e)
+		fastpathTV.EncMapIntFloat64V(v, fastpathCheckNilTrue, e)
 	case *map[int]float64:
-		fastpathTV.EncMapIntFloat64V(*v, e)
+		fastpathTV.EncMapIntFloat64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int]bool:
-		fastpathTV.EncMapIntBoolV(v, e)
+		fastpathTV.EncMapIntBoolV(v, fastpathCheckNilTrue, e)
 	case *map[int]bool:
-		fastpathTV.EncMapIntBoolV(*v, e)
+		fastpathTV.EncMapIntBoolV(*v, fastpathCheckNilTrue, e)
+
+	case []int8:
+		fastpathTV.EncSliceInt8V(v, fastpathCheckNilTrue, e)
+	case *[]int8:
+		fastpathTV.EncSliceInt8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]interface{}:
-		fastpathTV.EncMapInt8IntfV(v, e)
+		fastpathTV.EncMapInt8IntfV(v, fastpathCheckNilTrue, e)
 	case *map[int8]interface{}:
-		fastpathTV.EncMapInt8IntfV(*v, e)
+		fastpathTV.EncMapInt8IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]string:
-		fastpathTV.EncMapInt8StringV(v, e)
+		fastpathTV.EncMapInt8StringV(v, fastpathCheckNilTrue, e)
 	case *map[int8]string:
-		fastpathTV.EncMapInt8StringV(*v, e)
+		fastpathTV.EncMapInt8StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]uint:
-		fastpathTV.EncMapInt8UintV(v, e)
+		fastpathTV.EncMapInt8UintV(v, fastpathCheckNilTrue, e)
 	case *map[int8]uint:
-		fastpathTV.EncMapInt8UintV(*v, e)
+		fastpathTV.EncMapInt8UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]uint8:
-		fastpathTV.EncMapInt8Uint8V(v, e)
+		fastpathTV.EncMapInt8Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[int8]uint8:
-		fastpathTV.EncMapInt8Uint8V(*v, e)
+		fastpathTV.EncMapInt8Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]uint16:
-		fastpathTV.EncMapInt8Uint16V(v, e)
+		fastpathTV.EncMapInt8Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[int8]uint16:
-		fastpathTV.EncMapInt8Uint16V(*v, e)
+		fastpathTV.EncMapInt8Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]uint32:
-		fastpathTV.EncMapInt8Uint32V(v, e)
+		fastpathTV.EncMapInt8Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[int8]uint32:
-		fastpathTV.EncMapInt8Uint32V(*v, e)
+		fastpathTV.EncMapInt8Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]uint64:
-		fastpathTV.EncMapInt8Uint64V(v, e)
+		fastpathTV.EncMapInt8Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[int8]uint64:
-		fastpathTV.EncMapInt8Uint64V(*v, e)
+		fastpathTV.EncMapInt8Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]uintptr:
-		fastpathTV.EncMapInt8UintptrV(v, e)
+		fastpathTV.EncMapInt8UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[int8]uintptr:
-		fastpathTV.EncMapInt8UintptrV(*v, e)
+		fastpathTV.EncMapInt8UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]int:
-		fastpathTV.EncMapInt8IntV(v, e)
+		fastpathTV.EncMapInt8IntV(v, fastpathCheckNilTrue, e)
 	case *map[int8]int:
-		fastpathTV.EncMapInt8IntV(*v, e)
+		fastpathTV.EncMapInt8IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]int8:
-		fastpathTV.EncMapInt8Int8V(v, e)
+		fastpathTV.EncMapInt8Int8V(v, fastpathCheckNilTrue, e)
 	case *map[int8]int8:
-		fastpathTV.EncMapInt8Int8V(*v, e)
+		fastpathTV.EncMapInt8Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]int16:
-		fastpathTV.EncMapInt8Int16V(v, e)
+		fastpathTV.EncMapInt8Int16V(v, fastpathCheckNilTrue, e)
 	case *map[int8]int16:
-		fastpathTV.EncMapInt8Int16V(*v, e)
+		fastpathTV.EncMapInt8Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]int32:
-		fastpathTV.EncMapInt8Int32V(v, e)
+		fastpathTV.EncMapInt8Int32V(v, fastpathCheckNilTrue, e)
 	case *map[int8]int32:
-		fastpathTV.EncMapInt8Int32V(*v, e)
+		fastpathTV.EncMapInt8Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]int64:
-		fastpathTV.EncMapInt8Int64V(v, e)
+		fastpathTV.EncMapInt8Int64V(v, fastpathCheckNilTrue, e)
 	case *map[int8]int64:
-		fastpathTV.EncMapInt8Int64V(*v, e)
+		fastpathTV.EncMapInt8Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]float32:
-		fastpathTV.EncMapInt8Float32V(v, e)
+		fastpathTV.EncMapInt8Float32V(v, fastpathCheckNilTrue, e)
 	case *map[int8]float32:
-		fastpathTV.EncMapInt8Float32V(*v, e)
+		fastpathTV.EncMapInt8Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]float64:
-		fastpathTV.EncMapInt8Float64V(v, e)
+		fastpathTV.EncMapInt8Float64V(v, fastpathCheckNilTrue, e)
 	case *map[int8]float64:
-		fastpathTV.EncMapInt8Float64V(*v, e)
+		fastpathTV.EncMapInt8Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int8]bool:
-		fastpathTV.EncMapInt8BoolV(v, e)
+		fastpathTV.EncMapInt8BoolV(v, fastpathCheckNilTrue, e)
 	case *map[int8]bool:
-		fastpathTV.EncMapInt8BoolV(*v, e)
+		fastpathTV.EncMapInt8BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []int16:
+		fastpathTV.EncSliceInt16V(v, fastpathCheckNilTrue, e)
+	case *[]int16:
+		fastpathTV.EncSliceInt16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]interface{}:
-		fastpathTV.EncMapInt16IntfV(v, e)
+		fastpathTV.EncMapInt16IntfV(v, fastpathCheckNilTrue, e)
 	case *map[int16]interface{}:
-		fastpathTV.EncMapInt16IntfV(*v, e)
+		fastpathTV.EncMapInt16IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]string:
-		fastpathTV.EncMapInt16StringV(v, e)
+		fastpathTV.EncMapInt16StringV(v, fastpathCheckNilTrue, e)
 	case *map[int16]string:
-		fastpathTV.EncMapInt16StringV(*v, e)
+		fastpathTV.EncMapInt16StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]uint:
-		fastpathTV.EncMapInt16UintV(v, e)
+		fastpathTV.EncMapInt16UintV(v, fastpathCheckNilTrue, e)
 	case *map[int16]uint:
-		fastpathTV.EncMapInt16UintV(*v, e)
+		fastpathTV.EncMapInt16UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]uint8:
-		fastpathTV.EncMapInt16Uint8V(v, e)
+		fastpathTV.EncMapInt16Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[int16]uint8:
-		fastpathTV.EncMapInt16Uint8V(*v, e)
+		fastpathTV.EncMapInt16Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]uint16:
-		fastpathTV.EncMapInt16Uint16V(v, e)
+		fastpathTV.EncMapInt16Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[int16]uint16:
-		fastpathTV.EncMapInt16Uint16V(*v, e)
+		fastpathTV.EncMapInt16Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]uint32:
-		fastpathTV.EncMapInt16Uint32V(v, e)
+		fastpathTV.EncMapInt16Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[int16]uint32:
-		fastpathTV.EncMapInt16Uint32V(*v, e)
+		fastpathTV.EncMapInt16Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]uint64:
-		fastpathTV.EncMapInt16Uint64V(v, e)
+		fastpathTV.EncMapInt16Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[int16]uint64:
-		fastpathTV.EncMapInt16Uint64V(*v, e)
+		fastpathTV.EncMapInt16Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]uintptr:
-		fastpathTV.EncMapInt16UintptrV(v, e)
+		fastpathTV.EncMapInt16UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[int16]uintptr:
-		fastpathTV.EncMapInt16UintptrV(*v, e)
+		fastpathTV.EncMapInt16UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]int:
-		fastpathTV.EncMapInt16IntV(v, e)
+		fastpathTV.EncMapInt16IntV(v, fastpathCheckNilTrue, e)
 	case *map[int16]int:
-		fastpathTV.EncMapInt16IntV(*v, e)
+		fastpathTV.EncMapInt16IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]int8:
-		fastpathTV.EncMapInt16Int8V(v, e)
+		fastpathTV.EncMapInt16Int8V(v, fastpathCheckNilTrue, e)
 	case *map[int16]int8:
-		fastpathTV.EncMapInt16Int8V(*v, e)
+		fastpathTV.EncMapInt16Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]int16:
-		fastpathTV.EncMapInt16Int16V(v, e)
+		fastpathTV.EncMapInt16Int16V(v, fastpathCheckNilTrue, e)
 	case *map[int16]int16:
-		fastpathTV.EncMapInt16Int16V(*v, e)
+		fastpathTV.EncMapInt16Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]int32:
-		fastpathTV.EncMapInt16Int32V(v, e)
+		fastpathTV.EncMapInt16Int32V(v, fastpathCheckNilTrue, e)
 	case *map[int16]int32:
-		fastpathTV.EncMapInt16Int32V(*v, e)
+		fastpathTV.EncMapInt16Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]int64:
-		fastpathTV.EncMapInt16Int64V(v, e)
+		fastpathTV.EncMapInt16Int64V(v, fastpathCheckNilTrue, e)
 	case *map[int16]int64:
-		fastpathTV.EncMapInt16Int64V(*v, e)
+		fastpathTV.EncMapInt16Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]float32:
-		fastpathTV.EncMapInt16Float32V(v, e)
+		fastpathTV.EncMapInt16Float32V(v, fastpathCheckNilTrue, e)
 	case *map[int16]float32:
-		fastpathTV.EncMapInt16Float32V(*v, e)
+		fastpathTV.EncMapInt16Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]float64:
-		fastpathTV.EncMapInt16Float64V(v, e)
+		fastpathTV.EncMapInt16Float64V(v, fastpathCheckNilTrue, e)
 	case *map[int16]float64:
-		fastpathTV.EncMapInt16Float64V(*v, e)
+		fastpathTV.EncMapInt16Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int16]bool:
-		fastpathTV.EncMapInt16BoolV(v, e)
+		fastpathTV.EncMapInt16BoolV(v, fastpathCheckNilTrue, e)
 	case *map[int16]bool:
-		fastpathTV.EncMapInt16BoolV(*v, e)
+		fastpathTV.EncMapInt16BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []int32:
+		fastpathTV.EncSliceInt32V(v, fastpathCheckNilTrue, e)
+	case *[]int32:
+		fastpathTV.EncSliceInt32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]interface{}:
-		fastpathTV.EncMapInt32IntfV(v, e)
+		fastpathTV.EncMapInt32IntfV(v, fastpathCheckNilTrue, e)
 	case *map[int32]interface{}:
-		fastpathTV.EncMapInt32IntfV(*v, e)
+		fastpathTV.EncMapInt32IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]string:
-		fastpathTV.EncMapInt32StringV(v, e)
+		fastpathTV.EncMapInt32StringV(v, fastpathCheckNilTrue, e)
 	case *map[int32]string:
-		fastpathTV.EncMapInt32StringV(*v, e)
+		fastpathTV.EncMapInt32StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]uint:
-		fastpathTV.EncMapInt32UintV(v, e)
+		fastpathTV.EncMapInt32UintV(v, fastpathCheckNilTrue, e)
 	case *map[int32]uint:
-		fastpathTV.EncMapInt32UintV(*v, e)
+		fastpathTV.EncMapInt32UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]uint8:
-		fastpathTV.EncMapInt32Uint8V(v, e)
+		fastpathTV.EncMapInt32Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[int32]uint8:
-		fastpathTV.EncMapInt32Uint8V(*v, e)
+		fastpathTV.EncMapInt32Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]uint16:
-		fastpathTV.EncMapInt32Uint16V(v, e)
+		fastpathTV.EncMapInt32Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[int32]uint16:
-		fastpathTV.EncMapInt32Uint16V(*v, e)
+		fastpathTV.EncMapInt32Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]uint32:
-		fastpathTV.EncMapInt32Uint32V(v, e)
+		fastpathTV.EncMapInt32Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[int32]uint32:
-		fastpathTV.EncMapInt32Uint32V(*v, e)
+		fastpathTV.EncMapInt32Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]uint64:
-		fastpathTV.EncMapInt32Uint64V(v, e)
+		fastpathTV.EncMapInt32Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[int32]uint64:
-		fastpathTV.EncMapInt32Uint64V(*v, e)
+		fastpathTV.EncMapInt32Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]uintptr:
-		fastpathTV.EncMapInt32UintptrV(v, e)
+		fastpathTV.EncMapInt32UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[int32]uintptr:
-		fastpathTV.EncMapInt32UintptrV(*v, e)
+		fastpathTV.EncMapInt32UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]int:
-		fastpathTV.EncMapInt32IntV(v, e)
+		fastpathTV.EncMapInt32IntV(v, fastpathCheckNilTrue, e)
 	case *map[int32]int:
-		fastpathTV.EncMapInt32IntV(*v, e)
+		fastpathTV.EncMapInt32IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]int8:
-		fastpathTV.EncMapInt32Int8V(v, e)
+		fastpathTV.EncMapInt32Int8V(v, fastpathCheckNilTrue, e)
 	case *map[int32]int8:
-		fastpathTV.EncMapInt32Int8V(*v, e)
+		fastpathTV.EncMapInt32Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]int16:
-		fastpathTV.EncMapInt32Int16V(v, e)
+		fastpathTV.EncMapInt32Int16V(v, fastpathCheckNilTrue, e)
 	case *map[int32]int16:
-		fastpathTV.EncMapInt32Int16V(*v, e)
+		fastpathTV.EncMapInt32Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]int32:
-		fastpathTV.EncMapInt32Int32V(v, e)
+		fastpathTV.EncMapInt32Int32V(v, fastpathCheckNilTrue, e)
 	case *map[int32]int32:
-		fastpathTV.EncMapInt32Int32V(*v, e)
+		fastpathTV.EncMapInt32Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]int64:
-		fastpathTV.EncMapInt32Int64V(v, e)
+		fastpathTV.EncMapInt32Int64V(v, fastpathCheckNilTrue, e)
 	case *map[int32]int64:
-		fastpathTV.EncMapInt32Int64V(*v, e)
+		fastpathTV.EncMapInt32Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]float32:
-		fastpathTV.EncMapInt32Float32V(v, e)
+		fastpathTV.EncMapInt32Float32V(v, fastpathCheckNilTrue, e)
 	case *map[int32]float32:
-		fastpathTV.EncMapInt32Float32V(*v, e)
+		fastpathTV.EncMapInt32Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]float64:
-		fastpathTV.EncMapInt32Float64V(v, e)
+		fastpathTV.EncMapInt32Float64V(v, fastpathCheckNilTrue, e)
 	case *map[int32]float64:
-		fastpathTV.EncMapInt32Float64V(*v, e)
+		fastpathTV.EncMapInt32Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int32]bool:
-		fastpathTV.EncMapInt32BoolV(v, e)
+		fastpathTV.EncMapInt32BoolV(v, fastpathCheckNilTrue, e)
 	case *map[int32]bool:
-		fastpathTV.EncMapInt32BoolV(*v, e)
+		fastpathTV.EncMapInt32BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []int64:
+		fastpathTV.EncSliceInt64V(v, fastpathCheckNilTrue, e)
+	case *[]int64:
+		fastpathTV.EncSliceInt64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]interface{}:
-		fastpathTV.EncMapInt64IntfV(v, e)
+		fastpathTV.EncMapInt64IntfV(v, fastpathCheckNilTrue, e)
 	case *map[int64]interface{}:
-		fastpathTV.EncMapInt64IntfV(*v, e)
+		fastpathTV.EncMapInt64IntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]string:
-		fastpathTV.EncMapInt64StringV(v, e)
+		fastpathTV.EncMapInt64StringV(v, fastpathCheckNilTrue, e)
 	case *map[int64]string:
-		fastpathTV.EncMapInt64StringV(*v, e)
+		fastpathTV.EncMapInt64StringV(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]uint:
-		fastpathTV.EncMapInt64UintV(v, e)
+		fastpathTV.EncMapInt64UintV(v, fastpathCheckNilTrue, e)
 	case *map[int64]uint:
-		fastpathTV.EncMapInt64UintV(*v, e)
+		fastpathTV.EncMapInt64UintV(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]uint8:
-		fastpathTV.EncMapInt64Uint8V(v, e)
+		fastpathTV.EncMapInt64Uint8V(v, fastpathCheckNilTrue, e)
 	case *map[int64]uint8:
-		fastpathTV.EncMapInt64Uint8V(*v, e)
+		fastpathTV.EncMapInt64Uint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]uint16:
-		fastpathTV.EncMapInt64Uint16V(v, e)
+		fastpathTV.EncMapInt64Uint16V(v, fastpathCheckNilTrue, e)
 	case *map[int64]uint16:
-		fastpathTV.EncMapInt64Uint16V(*v, e)
+		fastpathTV.EncMapInt64Uint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]uint32:
-		fastpathTV.EncMapInt64Uint32V(v, e)
+		fastpathTV.EncMapInt64Uint32V(v, fastpathCheckNilTrue, e)
 	case *map[int64]uint32:
-		fastpathTV.EncMapInt64Uint32V(*v, e)
+		fastpathTV.EncMapInt64Uint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]uint64:
-		fastpathTV.EncMapInt64Uint64V(v, e)
+		fastpathTV.EncMapInt64Uint64V(v, fastpathCheckNilTrue, e)
 	case *map[int64]uint64:
-		fastpathTV.EncMapInt64Uint64V(*v, e)
+		fastpathTV.EncMapInt64Uint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]uintptr:
-		fastpathTV.EncMapInt64UintptrV(v, e)
+		fastpathTV.EncMapInt64UintptrV(v, fastpathCheckNilTrue, e)
 	case *map[int64]uintptr:
-		fastpathTV.EncMapInt64UintptrV(*v, e)
+		fastpathTV.EncMapInt64UintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]int:
-		fastpathTV.EncMapInt64IntV(v, e)
+		fastpathTV.EncMapInt64IntV(v, fastpathCheckNilTrue, e)
 	case *map[int64]int:
-		fastpathTV.EncMapInt64IntV(*v, e)
+		fastpathTV.EncMapInt64IntV(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]int8:
-		fastpathTV.EncMapInt64Int8V(v, e)
+		fastpathTV.EncMapInt64Int8V(v, fastpathCheckNilTrue, e)
 	case *map[int64]int8:
-		fastpathTV.EncMapInt64Int8V(*v, e)
+		fastpathTV.EncMapInt64Int8V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]int16:
-		fastpathTV.EncMapInt64Int16V(v, e)
+		fastpathTV.EncMapInt64Int16V(v, fastpathCheckNilTrue, e)
 	case *map[int64]int16:
-		fastpathTV.EncMapInt64Int16V(*v, e)
+		fastpathTV.EncMapInt64Int16V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]int32:
-		fastpathTV.EncMapInt64Int32V(v, e)
+		fastpathTV.EncMapInt64Int32V(v, fastpathCheckNilTrue, e)
 	case *map[int64]int32:
-		fastpathTV.EncMapInt64Int32V(*v, e)
+		fastpathTV.EncMapInt64Int32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]int64:
-		fastpathTV.EncMapInt64Int64V(v, e)
+		fastpathTV.EncMapInt64Int64V(v, fastpathCheckNilTrue, e)
 	case *map[int64]int64:
-		fastpathTV.EncMapInt64Int64V(*v, e)
+		fastpathTV.EncMapInt64Int64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]float32:
-		fastpathTV.EncMapInt64Float32V(v, e)
+		fastpathTV.EncMapInt64Float32V(v, fastpathCheckNilTrue, e)
 	case *map[int64]float32:
-		fastpathTV.EncMapInt64Float32V(*v, e)
+		fastpathTV.EncMapInt64Float32V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]float64:
-		fastpathTV.EncMapInt64Float64V(v, e)
+		fastpathTV.EncMapInt64Float64V(v, fastpathCheckNilTrue, e)
 	case *map[int64]float64:
-		fastpathTV.EncMapInt64Float64V(*v, e)
+		fastpathTV.EncMapInt64Float64V(*v, fastpathCheckNilTrue, e)
+
 	case map[int64]bool:
-		fastpathTV.EncMapInt64BoolV(v, e)
+		fastpathTV.EncMapInt64BoolV(v, fastpathCheckNilTrue, e)
 	case *map[int64]bool:
-		fastpathTV.EncMapInt64BoolV(*v, e)
+		fastpathTV.EncMapInt64BoolV(*v, fastpathCheckNilTrue, e)
+
+	case []bool:
+		fastpathTV.EncSliceBoolV(v, fastpathCheckNilTrue, e)
+	case *[]bool:
+		fastpathTV.EncSliceBoolV(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]interface{}:
-		fastpathTV.EncMapBoolIntfV(v, e)
+		fastpathTV.EncMapBoolIntfV(v, fastpathCheckNilTrue, e)
 	case *map[bool]interface{}:
-		fastpathTV.EncMapBoolIntfV(*v, e)
+		fastpathTV.EncMapBoolIntfV(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]string:
-		fastpathTV.EncMapBoolStringV(v, e)
+		fastpathTV.EncMapBoolStringV(v, fastpathCheckNilTrue, e)
 	case *map[bool]string:
-		fastpathTV.EncMapBoolStringV(*v, e)
+		fastpathTV.EncMapBoolStringV(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]uint:
-		fastpathTV.EncMapBoolUintV(v, e)
+		fastpathTV.EncMapBoolUintV(v, fastpathCheckNilTrue, e)
 	case *map[bool]uint:
-		fastpathTV.EncMapBoolUintV(*v, e)
+		fastpathTV.EncMapBoolUintV(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]uint8:
-		fastpathTV.EncMapBoolUint8V(v, e)
+		fastpathTV.EncMapBoolUint8V(v, fastpathCheckNilTrue, e)
 	case *map[bool]uint8:
-		fastpathTV.EncMapBoolUint8V(*v, e)
+		fastpathTV.EncMapBoolUint8V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]uint16:
-		fastpathTV.EncMapBoolUint16V(v, e)
+		fastpathTV.EncMapBoolUint16V(v, fastpathCheckNilTrue, e)
 	case *map[bool]uint16:
-		fastpathTV.EncMapBoolUint16V(*v, e)
+		fastpathTV.EncMapBoolUint16V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]uint32:
-		fastpathTV.EncMapBoolUint32V(v, e)
+		fastpathTV.EncMapBoolUint32V(v, fastpathCheckNilTrue, e)
 	case *map[bool]uint32:
-		fastpathTV.EncMapBoolUint32V(*v, e)
+		fastpathTV.EncMapBoolUint32V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]uint64:
-		fastpathTV.EncMapBoolUint64V(v, e)
+		fastpathTV.EncMapBoolUint64V(v, fastpathCheckNilTrue, e)
 	case *map[bool]uint64:
-		fastpathTV.EncMapBoolUint64V(*v, e)
+		fastpathTV.EncMapBoolUint64V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]uintptr:
-		fastpathTV.EncMapBoolUintptrV(v, e)
+		fastpathTV.EncMapBoolUintptrV(v, fastpathCheckNilTrue, e)
 	case *map[bool]uintptr:
-		fastpathTV.EncMapBoolUintptrV(*v, e)
+		fastpathTV.EncMapBoolUintptrV(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]int:
-		fastpathTV.EncMapBoolIntV(v, e)
+		fastpathTV.EncMapBoolIntV(v, fastpathCheckNilTrue, e)
 	case *map[bool]int:
-		fastpathTV.EncMapBoolIntV(*v, e)
+		fastpathTV.EncMapBoolIntV(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]int8:
-		fastpathTV.EncMapBoolInt8V(v, e)
+		fastpathTV.EncMapBoolInt8V(v, fastpathCheckNilTrue, e)
 	case *map[bool]int8:
-		fastpathTV.EncMapBoolInt8V(*v, e)
+		fastpathTV.EncMapBoolInt8V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]int16:
-		fastpathTV.EncMapBoolInt16V(v, e)
+		fastpathTV.EncMapBoolInt16V(v, fastpathCheckNilTrue, e)
 	case *map[bool]int16:
-		fastpathTV.EncMapBoolInt16V(*v, e)
+		fastpathTV.EncMapBoolInt16V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]int32:
-		fastpathTV.EncMapBoolInt32V(v, e)
+		fastpathTV.EncMapBoolInt32V(v, fastpathCheckNilTrue, e)
 	case *map[bool]int32:
-		fastpathTV.EncMapBoolInt32V(*v, e)
+		fastpathTV.EncMapBoolInt32V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]int64:
-		fastpathTV.EncMapBoolInt64V(v, e)
+		fastpathTV.EncMapBoolInt64V(v, fastpathCheckNilTrue, e)
 	case *map[bool]int64:
-		fastpathTV.EncMapBoolInt64V(*v, e)
+		fastpathTV.EncMapBoolInt64V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]float32:
-		fastpathTV.EncMapBoolFloat32V(v, e)
+		fastpathTV.EncMapBoolFloat32V(v, fastpathCheckNilTrue, e)
 	case *map[bool]float32:
-		fastpathTV.EncMapBoolFloat32V(*v, e)
+		fastpathTV.EncMapBoolFloat32V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]float64:
-		fastpathTV.EncMapBoolFloat64V(v, e)
+		fastpathTV.EncMapBoolFloat64V(v, fastpathCheckNilTrue, e)
 	case *map[bool]float64:
-		fastpathTV.EncMapBoolFloat64V(*v, e)
+		fastpathTV.EncMapBoolFloat64V(*v, fastpathCheckNilTrue, e)
+
 	case map[bool]bool:
-		fastpathTV.EncMapBoolBoolV(v, e)
+		fastpathTV.EncMapBoolBoolV(v, fastpathCheckNilTrue, e)
 	case *map[bool]bool:
-		fastpathTV.EncMapBoolBoolV(*v, e)
+		fastpathTV.EncMapBoolBoolV(*v, fastpathCheckNilTrue, e)
 
 	default:
-		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
 		return false
 	}
 	return true
 }
 
-// -- -- fast path functions
+func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
 
-func (e *Encoder) fastpathEncSliceIntfR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceIntfV(rv2i(rv).([]interface{}), e)
-	} else {
-		fastpathTV.EncSliceIntfV(rv2i(rv).([]interface{}), e)
-	}
-}
-func (_ fastpathT) EncSliceIntfV(v []interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case []interface{}:
+		fastpathTV.EncSliceIntfV(v, fastpathCheckNilTrue, e)
+	case *[]interface{}:
+		fastpathTV.EncSliceIntfV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceStringR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceStringV(rv2i(rv).([]string), e)
-	} else {
-		fastpathTV.EncSliceStringV(rv2i(rv).([]string), e)
-	}
-}
-func (_ fastpathT) EncSliceStringV(v []string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeString(cUTF8, v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeString(cUTF8, v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceStringV(v []string, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeString(cUTF8, v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeString(cUTF8, v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case []string:
+		fastpathTV.EncSliceStringV(v, fastpathCheckNilTrue, e)
+	case *[]string:
+		fastpathTV.EncSliceStringV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceFloat32V(rv2i(rv).([]float32), e)
-	} else {
-		fastpathTV.EncSliceFloat32V(rv2i(rv).([]float32), e)
-	}
-}
-func (_ fastpathT) EncSliceFloat32V(v []float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeFloat32(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat32(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeFloat32(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat32(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case []float32:
+		fastpathTV.EncSliceFloat32V(v, fastpathCheckNilTrue, e)
+	case *[]float32:
+		fastpathTV.EncSliceFloat32V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceFloat64V(rv2i(rv).([]float64), e)
-	} else {
-		fastpathTV.EncSliceFloat64V(rv2i(rv).([]float64), e)
-	}
-}
-func (_ fastpathT) EncSliceFloat64V(v []float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeFloat64(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat64(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeFloat64(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat64(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case []float64:
+		fastpathTV.EncSliceFloat64V(v, fastpathCheckNilTrue, e)
+	case *[]float64:
+		fastpathTV.EncSliceFloat64V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceUintR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUintV(rv2i(rv).([]uint), e)
-	} else {
-		fastpathTV.EncSliceUintV(rv2i(rv).([]uint), e)
-	}
-}
-func (_ fastpathT) EncSliceUintV(v []uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUintV(v []uint, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case []uint:
+		fastpathTV.EncSliceUintV(v, fastpathCheckNilTrue, e)
+	case *[]uint:
+		fastpathTV.EncSliceUintV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceUint8R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint8V(rv2i(rv).([]uint8), e)
-	} else {
-		fastpathTV.EncSliceUint8V(rv2i(rv).([]uint8), e)
+	case []uint16:
+		fastpathTV.EncSliceUint16V(v, fastpathCheckNilTrue, e)
+	case *[]uint16:
+		fastpathTV.EncSliceUint16V(*v, fastpathCheckNilTrue, e)
+
+	case []uint32:
+		fastpathTV.EncSliceUint32V(v, fastpathCheckNilTrue, e)
+	case *[]uint32:
+		fastpathTV.EncSliceUint32V(*v, fastpathCheckNilTrue, e)
+
+	case []uint64:
+		fastpathTV.EncSliceUint64V(v, fastpathCheckNilTrue, e)
+	case *[]uint64:
+		fastpathTV.EncSliceUint64V(*v, fastpathCheckNilTrue, e)
+
+	case []uintptr:
+		fastpathTV.EncSliceUintptrV(v, fastpathCheckNilTrue, e)
+	case *[]uintptr:
+		fastpathTV.EncSliceUintptrV(*v, fastpathCheckNilTrue, e)
+
+	case []int:
+		fastpathTV.EncSliceIntV(v, fastpathCheckNilTrue, e)
+	case *[]int:
+		fastpathTV.EncSliceIntV(*v, fastpathCheckNilTrue, e)
+
+	case []int8:
+		fastpathTV.EncSliceInt8V(v, fastpathCheckNilTrue, e)
+	case *[]int8:
+		fastpathTV.EncSliceInt8V(*v, fastpathCheckNilTrue, e)
+
+	case []int16:
+		fastpathTV.EncSliceInt16V(v, fastpathCheckNilTrue, e)
+	case *[]int16:
+		fastpathTV.EncSliceInt16V(*v, fastpathCheckNilTrue, e)
+
+	case []int32:
+		fastpathTV.EncSliceInt32V(v, fastpathCheckNilTrue, e)
+	case *[]int32:
+		fastpathTV.EncSliceInt32V(*v, fastpathCheckNilTrue, e)
+
+	case []int64:
+		fastpathTV.EncSliceInt64V(v, fastpathCheckNilTrue, e)
+	case *[]int64:
+		fastpathTV.EncSliceInt64V(*v, fastpathCheckNilTrue, e)
+
+	case []bool:
+		fastpathTV.EncSliceBoolV(v, fastpathCheckNilTrue, e)
+	case *[]bool:
+		fastpathTV.EncSliceBoolV(*v, fastpathCheckNilTrue, e)
+
+	default:
+		_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
+		return false
 	}
-}
-func (_ fastpathT) EncSliceUint8V(v []uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint8V(v []uint8, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
+	return true
 }
 
-func (e *Encoder) fastpathEncSliceUint16R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint16V(rv2i(rv).([]uint16), e)
-	} else {
-		fastpathTV.EncSliceUint16V(rv2i(rv).([]uint16), e)
-	}
-}
-func (_ fastpathT) EncSliceUint16V(v []uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
 
-func (e *Encoder) fastpathEncSliceUint32R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint32V(rv2i(rv).([]uint32), e)
-	} else {
-		fastpathTV.EncSliceUint32V(rv2i(rv).([]uint32), e)
-	}
-}
-func (_ fastpathT) EncSliceUint32V(v []uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]interface{}:
+		fastpathTV.EncMapIntfIntfV(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]interface{}:
+		fastpathTV.EncMapIntfIntfV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceUint64R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint64V(rv2i(rv).([]uint64), e)
-	} else {
-		fastpathTV.EncSliceUint64V(rv2i(rv).([]uint64), e)
-	}
-}
-func (_ fastpathT) EncSliceUint64V(v []uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]string:
+		fastpathTV.EncMapIntfStringV(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]string:
+		fastpathTV.EncMapIntfStringV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUintptrV(rv2i(rv).([]uintptr), e)
-	} else {
-		fastpathTV.EncSliceUintptrV(rv2i(rv).([]uintptr), e)
-	}
-}
-func (_ fastpathT) EncSliceUintptrV(v []uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]uint:
+		fastpathTV.EncMapIntfUintV(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]uint:
+		fastpathTV.EncMapIntfUintV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceIntR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceIntV(rv2i(rv).([]int), e)
-	} else {
-		fastpathTV.EncSliceIntV(rv2i(rv).([]int), e)
-	}
-}
-func (_ fastpathT) EncSliceIntV(v []int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceIntV(v []int, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]uint8:
+		fastpathTV.EncMapIntfUint8V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]uint8:
+		fastpathTV.EncMapIntfUint8V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceInt8R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt8V(rv2i(rv).([]int8), e)
-	} else {
-		fastpathTV.EncSliceInt8V(rv2i(rv).([]int8), e)
-	}
-}
-func (_ fastpathT) EncSliceInt8V(v []int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt8V(v []int8, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]uint16:
+		fastpathTV.EncMapIntfUint16V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]uint16:
+		fastpathTV.EncMapIntfUint16V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceInt16R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt16V(rv2i(rv).([]int16), e)
-	} else {
-		fastpathTV.EncSliceInt16V(rv2i(rv).([]int16), e)
-	}
-}
-func (_ fastpathT) EncSliceInt16V(v []int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt16V(v []int16, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]uint32:
+		fastpathTV.EncMapIntfUint32V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]uint32:
+		fastpathTV.EncMapIntfUint32V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceInt32R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt32V(rv2i(rv).([]int32), e)
-	} else {
-		fastpathTV.EncSliceInt32V(rv2i(rv).([]int32), e)
-	}
-}
-func (_ fastpathT) EncSliceInt32V(v []int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt32V(v []int32, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]uint64:
+		fastpathTV.EncMapIntfUint64V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]uint64:
+		fastpathTV.EncMapIntfUint64V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceInt64R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt64V(rv2i(rv).([]int64), e)
-	} else {
-		fastpathTV.EncSliceInt64V(rv2i(rv).([]int64), e)
-	}
-}
-func (_ fastpathT) EncSliceInt64V(v []int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt64V(v []int64, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[interface{}]uintptr:
+		fastpathTV.EncMapIntfUintptrV(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]uintptr:
+		fastpathTV.EncMapIntfUintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]int:
+		fastpathTV.EncMapIntfIntV(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]int:
+		fastpathTV.EncMapIntfIntV(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]int8:
+		fastpathTV.EncMapIntfInt8V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]int8:
+		fastpathTV.EncMapIntfInt8V(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]int16:
+		fastpathTV.EncMapIntfInt16V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]int16:
+		fastpathTV.EncMapIntfInt16V(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]int32:
+		fastpathTV.EncMapIntfInt32V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]int32:
+		fastpathTV.EncMapIntfInt32V(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]int64:
+		fastpathTV.EncMapIntfInt64V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]int64:
+		fastpathTV.EncMapIntfInt64V(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]float32:
+		fastpathTV.EncMapIntfFloat32V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]float32:
+		fastpathTV.EncMapIntfFloat32V(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]float64:
+		fastpathTV.EncMapIntfFloat64V(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]float64:
+		fastpathTV.EncMapIntfFloat64V(*v, fastpathCheckNilTrue, e)
+
+	case map[interface{}]bool:
+		fastpathTV.EncMapIntfBoolV(v, fastpathCheckNilTrue, e)
+	case *map[interface{}]bool:
+		fastpathTV.EncMapIntfBoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[string]interface{}:
+		fastpathTV.EncMapStringIntfV(v, fastpathCheckNilTrue, e)
+	case *map[string]interface{}:
+		fastpathTV.EncMapStringIntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[string]string:
+		fastpathTV.EncMapStringStringV(v, fastpathCheckNilTrue, e)
+	case *map[string]string:
+		fastpathTV.EncMapStringStringV(*v, fastpathCheckNilTrue, e)
+
+	case map[string]uint:
+		fastpathTV.EncMapStringUintV(v, fastpathCheckNilTrue, e)
+	case *map[string]uint:
+		fastpathTV.EncMapStringUintV(*v, fastpathCheckNilTrue, e)
+
+	case map[string]uint8:
+		fastpathTV.EncMapStringUint8V(v, fastpathCheckNilTrue, e)
+	case *map[string]uint8:
+		fastpathTV.EncMapStringUint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]uint16:
+		fastpathTV.EncMapStringUint16V(v, fastpathCheckNilTrue, e)
+	case *map[string]uint16:
+		fastpathTV.EncMapStringUint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]uint32:
+		fastpathTV.EncMapStringUint32V(v, fastpathCheckNilTrue, e)
+	case *map[string]uint32:
+		fastpathTV.EncMapStringUint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]uint64:
+		fastpathTV.EncMapStringUint64V(v, fastpathCheckNilTrue, e)
+	case *map[string]uint64:
+		fastpathTV.EncMapStringUint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]uintptr:
+		fastpathTV.EncMapStringUintptrV(v, fastpathCheckNilTrue, e)
+	case *map[string]uintptr:
+		fastpathTV.EncMapStringUintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[string]int:
+		fastpathTV.EncMapStringIntV(v, fastpathCheckNilTrue, e)
+	case *map[string]int:
+		fastpathTV.EncMapStringIntV(*v, fastpathCheckNilTrue, e)
+
+	case map[string]int8:
+		fastpathTV.EncMapStringInt8V(v, fastpathCheckNilTrue, e)
+	case *map[string]int8:
+		fastpathTV.EncMapStringInt8V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]int16:
+		fastpathTV.EncMapStringInt16V(v, fastpathCheckNilTrue, e)
+	case *map[string]int16:
+		fastpathTV.EncMapStringInt16V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]int32:
+		fastpathTV.EncMapStringInt32V(v, fastpathCheckNilTrue, e)
+	case *map[string]int32:
+		fastpathTV.EncMapStringInt32V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]int64:
+		fastpathTV.EncMapStringInt64V(v, fastpathCheckNilTrue, e)
+	case *map[string]int64:
+		fastpathTV.EncMapStringInt64V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]float32:
+		fastpathTV.EncMapStringFloat32V(v, fastpathCheckNilTrue, e)
+	case *map[string]float32:
+		fastpathTV.EncMapStringFloat32V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]float64:
+		fastpathTV.EncMapStringFloat64V(v, fastpathCheckNilTrue, e)
+	case *map[string]float64:
+		fastpathTV.EncMapStringFloat64V(*v, fastpathCheckNilTrue, e)
+
+	case map[string]bool:
+		fastpathTV.EncMapStringBoolV(v, fastpathCheckNilTrue, e)
+	case *map[string]bool:
+		fastpathTV.EncMapStringBoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]interface{}:
+		fastpathTV.EncMapFloat32IntfV(v, fastpathCheckNilTrue, e)
+	case *map[float32]interface{}:
+		fastpathTV.EncMapFloat32IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]string:
+		fastpathTV.EncMapFloat32StringV(v, fastpathCheckNilTrue, e)
+	case *map[float32]string:
+		fastpathTV.EncMapFloat32StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]uint:
+		fastpathTV.EncMapFloat32UintV(v, fastpathCheckNilTrue, e)
+	case *map[float32]uint:
+		fastpathTV.EncMapFloat32UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]uint8:
+		fastpathTV.EncMapFloat32Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[float32]uint8:
+		fastpathTV.EncMapFloat32Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]uint16:
+		fastpathTV.EncMapFloat32Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[float32]uint16:
+		fastpathTV.EncMapFloat32Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]uint32:
+		fastpathTV.EncMapFloat32Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[float32]uint32:
+		fastpathTV.EncMapFloat32Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]uint64:
+		fastpathTV.EncMapFloat32Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[float32]uint64:
+		fastpathTV.EncMapFloat32Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]uintptr:
+		fastpathTV.EncMapFloat32UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[float32]uintptr:
+		fastpathTV.EncMapFloat32UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]int:
+		fastpathTV.EncMapFloat32IntV(v, fastpathCheckNilTrue, e)
+	case *map[float32]int:
+		fastpathTV.EncMapFloat32IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]int8:
+		fastpathTV.EncMapFloat32Int8V(v, fastpathCheckNilTrue, e)
+	case *map[float32]int8:
+		fastpathTV.EncMapFloat32Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]int16:
+		fastpathTV.EncMapFloat32Int16V(v, fastpathCheckNilTrue, e)
+	case *map[float32]int16:
+		fastpathTV.EncMapFloat32Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]int32:
+		fastpathTV.EncMapFloat32Int32V(v, fastpathCheckNilTrue, e)
+	case *map[float32]int32:
+		fastpathTV.EncMapFloat32Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]int64:
+		fastpathTV.EncMapFloat32Int64V(v, fastpathCheckNilTrue, e)
+	case *map[float32]int64:
+		fastpathTV.EncMapFloat32Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]float32:
+		fastpathTV.EncMapFloat32Float32V(v, fastpathCheckNilTrue, e)
+	case *map[float32]float32:
+		fastpathTV.EncMapFloat32Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]float64:
+		fastpathTV.EncMapFloat32Float64V(v, fastpathCheckNilTrue, e)
+	case *map[float32]float64:
+		fastpathTV.EncMapFloat32Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[float32]bool:
+		fastpathTV.EncMapFloat32BoolV(v, fastpathCheckNilTrue, e)
+	case *map[float32]bool:
+		fastpathTV.EncMapFloat32BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]interface{}:
+		fastpathTV.EncMapFloat64IntfV(v, fastpathCheckNilTrue, e)
+	case *map[float64]interface{}:
+		fastpathTV.EncMapFloat64IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]string:
+		fastpathTV.EncMapFloat64StringV(v, fastpathCheckNilTrue, e)
+	case *map[float64]string:
+		fastpathTV.EncMapFloat64StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]uint:
+		fastpathTV.EncMapFloat64UintV(v, fastpathCheckNilTrue, e)
+	case *map[float64]uint:
+		fastpathTV.EncMapFloat64UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]uint8:
+		fastpathTV.EncMapFloat64Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[float64]uint8:
+		fastpathTV.EncMapFloat64Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]uint16:
+		fastpathTV.EncMapFloat64Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[float64]uint16:
+		fastpathTV.EncMapFloat64Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]uint32:
+		fastpathTV.EncMapFloat64Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[float64]uint32:
+		fastpathTV.EncMapFloat64Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]uint64:
+		fastpathTV.EncMapFloat64Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[float64]uint64:
+		fastpathTV.EncMapFloat64Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]uintptr:
+		fastpathTV.EncMapFloat64UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[float64]uintptr:
+		fastpathTV.EncMapFloat64UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]int:
+		fastpathTV.EncMapFloat64IntV(v, fastpathCheckNilTrue, e)
+	case *map[float64]int:
+		fastpathTV.EncMapFloat64IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]int8:
+		fastpathTV.EncMapFloat64Int8V(v, fastpathCheckNilTrue, e)
+	case *map[float64]int8:
+		fastpathTV.EncMapFloat64Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]int16:
+		fastpathTV.EncMapFloat64Int16V(v, fastpathCheckNilTrue, e)
+	case *map[float64]int16:
+		fastpathTV.EncMapFloat64Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]int32:
+		fastpathTV.EncMapFloat64Int32V(v, fastpathCheckNilTrue, e)
+	case *map[float64]int32:
+		fastpathTV.EncMapFloat64Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]int64:
+		fastpathTV.EncMapFloat64Int64V(v, fastpathCheckNilTrue, e)
+	case *map[float64]int64:
+		fastpathTV.EncMapFloat64Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]float32:
+		fastpathTV.EncMapFloat64Float32V(v, fastpathCheckNilTrue, e)
+	case *map[float64]float32:
+		fastpathTV.EncMapFloat64Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]float64:
+		fastpathTV.EncMapFloat64Float64V(v, fastpathCheckNilTrue, e)
+	case *map[float64]float64:
+		fastpathTV.EncMapFloat64Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[float64]bool:
+		fastpathTV.EncMapFloat64BoolV(v, fastpathCheckNilTrue, e)
+	case *map[float64]bool:
+		fastpathTV.EncMapFloat64BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]interface{}:
+		fastpathTV.EncMapUintIntfV(v, fastpathCheckNilTrue, e)
+	case *map[uint]interface{}:
+		fastpathTV.EncMapUintIntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]string:
+		fastpathTV.EncMapUintStringV(v, fastpathCheckNilTrue, e)
+	case *map[uint]string:
+		fastpathTV.EncMapUintStringV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]uint:
+		fastpathTV.EncMapUintUintV(v, fastpathCheckNilTrue, e)
+	case *map[uint]uint:
+		fastpathTV.EncMapUintUintV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]uint8:
+		fastpathTV.EncMapUintUint8V(v, fastpathCheckNilTrue, e)
+	case *map[uint]uint8:
+		fastpathTV.EncMapUintUint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]uint16:
+		fastpathTV.EncMapUintUint16V(v, fastpathCheckNilTrue, e)
+	case *map[uint]uint16:
+		fastpathTV.EncMapUintUint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]uint32:
+		fastpathTV.EncMapUintUint32V(v, fastpathCheckNilTrue, e)
+	case *map[uint]uint32:
+		fastpathTV.EncMapUintUint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]uint64:
+		fastpathTV.EncMapUintUint64V(v, fastpathCheckNilTrue, e)
+	case *map[uint]uint64:
+		fastpathTV.EncMapUintUint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]uintptr:
+		fastpathTV.EncMapUintUintptrV(v, fastpathCheckNilTrue, e)
+	case *map[uint]uintptr:
+		fastpathTV.EncMapUintUintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]int:
+		fastpathTV.EncMapUintIntV(v, fastpathCheckNilTrue, e)
+	case *map[uint]int:
+		fastpathTV.EncMapUintIntV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]int8:
+		fastpathTV.EncMapUintInt8V(v, fastpathCheckNilTrue, e)
+	case *map[uint]int8:
+		fastpathTV.EncMapUintInt8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]int16:
+		fastpathTV.EncMapUintInt16V(v, fastpathCheckNilTrue, e)
+	case *map[uint]int16:
+		fastpathTV.EncMapUintInt16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]int32:
+		fastpathTV.EncMapUintInt32V(v, fastpathCheckNilTrue, e)
+	case *map[uint]int32:
+		fastpathTV.EncMapUintInt32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]int64:
+		fastpathTV.EncMapUintInt64V(v, fastpathCheckNilTrue, e)
+	case *map[uint]int64:
+		fastpathTV.EncMapUintInt64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]float32:
+		fastpathTV.EncMapUintFloat32V(v, fastpathCheckNilTrue, e)
+	case *map[uint]float32:
+		fastpathTV.EncMapUintFloat32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]float64:
+		fastpathTV.EncMapUintFloat64V(v, fastpathCheckNilTrue, e)
+	case *map[uint]float64:
+		fastpathTV.EncMapUintFloat64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint]bool:
+		fastpathTV.EncMapUintBoolV(v, fastpathCheckNilTrue, e)
+	case *map[uint]bool:
+		fastpathTV.EncMapUintBoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]interface{}:
+		fastpathTV.EncMapUint8IntfV(v, fastpathCheckNilTrue, e)
+	case *map[uint8]interface{}:
+		fastpathTV.EncMapUint8IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]string:
+		fastpathTV.EncMapUint8StringV(v, fastpathCheckNilTrue, e)
+	case *map[uint8]string:
+		fastpathTV.EncMapUint8StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]uint:
+		fastpathTV.EncMapUint8UintV(v, fastpathCheckNilTrue, e)
+	case *map[uint8]uint:
+		fastpathTV.EncMapUint8UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]uint8:
+		fastpathTV.EncMapUint8Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]uint8:
+		fastpathTV.EncMapUint8Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]uint16:
+		fastpathTV.EncMapUint8Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]uint16:
+		fastpathTV.EncMapUint8Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]uint32:
+		fastpathTV.EncMapUint8Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]uint32:
+		fastpathTV.EncMapUint8Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]uint64:
+		fastpathTV.EncMapUint8Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]uint64:
+		fastpathTV.EncMapUint8Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]uintptr:
+		fastpathTV.EncMapUint8UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[uint8]uintptr:
+		fastpathTV.EncMapUint8UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]int:
+		fastpathTV.EncMapUint8IntV(v, fastpathCheckNilTrue, e)
+	case *map[uint8]int:
+		fastpathTV.EncMapUint8IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]int8:
+		fastpathTV.EncMapUint8Int8V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]int8:
+		fastpathTV.EncMapUint8Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]int16:
+		fastpathTV.EncMapUint8Int16V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]int16:
+		fastpathTV.EncMapUint8Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]int32:
+		fastpathTV.EncMapUint8Int32V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]int32:
+		fastpathTV.EncMapUint8Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]int64:
+		fastpathTV.EncMapUint8Int64V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]int64:
+		fastpathTV.EncMapUint8Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]float32:
+		fastpathTV.EncMapUint8Float32V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]float32:
+		fastpathTV.EncMapUint8Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]float64:
+		fastpathTV.EncMapUint8Float64V(v, fastpathCheckNilTrue, e)
+	case *map[uint8]float64:
+		fastpathTV.EncMapUint8Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint8]bool:
+		fastpathTV.EncMapUint8BoolV(v, fastpathCheckNilTrue, e)
+	case *map[uint8]bool:
+		fastpathTV.EncMapUint8BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]interface{}:
+		fastpathTV.EncMapUint16IntfV(v, fastpathCheckNilTrue, e)
+	case *map[uint16]interface{}:
+		fastpathTV.EncMapUint16IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]string:
+		fastpathTV.EncMapUint16StringV(v, fastpathCheckNilTrue, e)
+	case *map[uint16]string:
+		fastpathTV.EncMapUint16StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]uint:
+		fastpathTV.EncMapUint16UintV(v, fastpathCheckNilTrue, e)
+	case *map[uint16]uint:
+		fastpathTV.EncMapUint16UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]uint8:
+		fastpathTV.EncMapUint16Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]uint8:
+		fastpathTV.EncMapUint16Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]uint16:
+		fastpathTV.EncMapUint16Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]uint16:
+		fastpathTV.EncMapUint16Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]uint32:
+		fastpathTV.EncMapUint16Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]uint32:
+		fastpathTV.EncMapUint16Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]uint64:
+		fastpathTV.EncMapUint16Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]uint64:
+		fastpathTV.EncMapUint16Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]uintptr:
+		fastpathTV.EncMapUint16UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[uint16]uintptr:
+		fastpathTV.EncMapUint16UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]int:
+		fastpathTV.EncMapUint16IntV(v, fastpathCheckNilTrue, e)
+	case *map[uint16]int:
+		fastpathTV.EncMapUint16IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]int8:
+		fastpathTV.EncMapUint16Int8V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]int8:
+		fastpathTV.EncMapUint16Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]int16:
+		fastpathTV.EncMapUint16Int16V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]int16:
+		fastpathTV.EncMapUint16Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]int32:
+		fastpathTV.EncMapUint16Int32V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]int32:
+		fastpathTV.EncMapUint16Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]int64:
+		fastpathTV.EncMapUint16Int64V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]int64:
+		fastpathTV.EncMapUint16Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]float32:
+		fastpathTV.EncMapUint16Float32V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]float32:
+		fastpathTV.EncMapUint16Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]float64:
+		fastpathTV.EncMapUint16Float64V(v, fastpathCheckNilTrue, e)
+	case *map[uint16]float64:
+		fastpathTV.EncMapUint16Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint16]bool:
+		fastpathTV.EncMapUint16BoolV(v, fastpathCheckNilTrue, e)
+	case *map[uint16]bool:
+		fastpathTV.EncMapUint16BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]interface{}:
+		fastpathTV.EncMapUint32IntfV(v, fastpathCheckNilTrue, e)
+	case *map[uint32]interface{}:
+		fastpathTV.EncMapUint32IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]string:
+		fastpathTV.EncMapUint32StringV(v, fastpathCheckNilTrue, e)
+	case *map[uint32]string:
+		fastpathTV.EncMapUint32StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]uint:
+		fastpathTV.EncMapUint32UintV(v, fastpathCheckNilTrue, e)
+	case *map[uint32]uint:
+		fastpathTV.EncMapUint32UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]uint8:
+		fastpathTV.EncMapUint32Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]uint8:
+		fastpathTV.EncMapUint32Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]uint16:
+		fastpathTV.EncMapUint32Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]uint16:
+		fastpathTV.EncMapUint32Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]uint32:
+		fastpathTV.EncMapUint32Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]uint32:
+		fastpathTV.EncMapUint32Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]uint64:
+		fastpathTV.EncMapUint32Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]uint64:
+		fastpathTV.EncMapUint32Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]uintptr:
+		fastpathTV.EncMapUint32UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[uint32]uintptr:
+		fastpathTV.EncMapUint32UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]int:
+		fastpathTV.EncMapUint32IntV(v, fastpathCheckNilTrue, e)
+	case *map[uint32]int:
+		fastpathTV.EncMapUint32IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]int8:
+		fastpathTV.EncMapUint32Int8V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]int8:
+		fastpathTV.EncMapUint32Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]int16:
+		fastpathTV.EncMapUint32Int16V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]int16:
+		fastpathTV.EncMapUint32Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]int32:
+		fastpathTV.EncMapUint32Int32V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]int32:
+		fastpathTV.EncMapUint32Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]int64:
+		fastpathTV.EncMapUint32Int64V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]int64:
+		fastpathTV.EncMapUint32Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]float32:
+		fastpathTV.EncMapUint32Float32V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]float32:
+		fastpathTV.EncMapUint32Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]float64:
+		fastpathTV.EncMapUint32Float64V(v, fastpathCheckNilTrue, e)
+	case *map[uint32]float64:
+		fastpathTV.EncMapUint32Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint32]bool:
+		fastpathTV.EncMapUint32BoolV(v, fastpathCheckNilTrue, e)
+	case *map[uint32]bool:
+		fastpathTV.EncMapUint32BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]interface{}:
+		fastpathTV.EncMapUint64IntfV(v, fastpathCheckNilTrue, e)
+	case *map[uint64]interface{}:
+		fastpathTV.EncMapUint64IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]string:
+		fastpathTV.EncMapUint64StringV(v, fastpathCheckNilTrue, e)
+	case *map[uint64]string:
+		fastpathTV.EncMapUint64StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]uint:
+		fastpathTV.EncMapUint64UintV(v, fastpathCheckNilTrue, e)
+	case *map[uint64]uint:
+		fastpathTV.EncMapUint64UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]uint8:
+		fastpathTV.EncMapUint64Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]uint8:
+		fastpathTV.EncMapUint64Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]uint16:
+		fastpathTV.EncMapUint64Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]uint16:
+		fastpathTV.EncMapUint64Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]uint32:
+		fastpathTV.EncMapUint64Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]uint32:
+		fastpathTV.EncMapUint64Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]uint64:
+		fastpathTV.EncMapUint64Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]uint64:
+		fastpathTV.EncMapUint64Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]uintptr:
+		fastpathTV.EncMapUint64UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[uint64]uintptr:
+		fastpathTV.EncMapUint64UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]int:
+		fastpathTV.EncMapUint64IntV(v, fastpathCheckNilTrue, e)
+	case *map[uint64]int:
+		fastpathTV.EncMapUint64IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]int8:
+		fastpathTV.EncMapUint64Int8V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]int8:
+		fastpathTV.EncMapUint64Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]int16:
+		fastpathTV.EncMapUint64Int16V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]int16:
+		fastpathTV.EncMapUint64Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]int32:
+		fastpathTV.EncMapUint64Int32V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]int32:
+		fastpathTV.EncMapUint64Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]int64:
+		fastpathTV.EncMapUint64Int64V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]int64:
+		fastpathTV.EncMapUint64Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]float32:
+		fastpathTV.EncMapUint64Float32V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]float32:
+		fastpathTV.EncMapUint64Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]float64:
+		fastpathTV.EncMapUint64Float64V(v, fastpathCheckNilTrue, e)
+	case *map[uint64]float64:
+		fastpathTV.EncMapUint64Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uint64]bool:
+		fastpathTV.EncMapUint64BoolV(v, fastpathCheckNilTrue, e)
+	case *map[uint64]bool:
+		fastpathTV.EncMapUint64BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]interface{}:
+		fastpathTV.EncMapUintptrIntfV(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]interface{}:
+		fastpathTV.EncMapUintptrIntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]string:
+		fastpathTV.EncMapUintptrStringV(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]string:
+		fastpathTV.EncMapUintptrStringV(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]uint:
+		fastpathTV.EncMapUintptrUintV(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]uint:
+		fastpathTV.EncMapUintptrUintV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncSliceBoolR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceBoolV(rv2i(rv).([]bool), e)
-	} else {
-		fastpathTV.EncSliceBoolV(rv2i(rv).([]bool), e)
-	}
-}
-func (_ fastpathT) EncSliceBoolV(v []bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeBool(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeBool(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceBoolV(v []bool, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeBool(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeBool(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[uintptr]uint8:
+		fastpathTV.EncMapUintptrUint8V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]uint8:
+		fastpathTV.EncMapUintptrUint8V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfIntfV(rv2i(rv).(map[interface{}]interface{}), e)
-}
-func (_ fastpathT) EncMapIntfIntfV(v map[interface{}]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[uintptr]uint16:
+		fastpathTV.EncMapUintptrUint16V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]uint16:
+		fastpathTV.EncMapUintptrUint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]uint32:
+		fastpathTV.EncMapUintptrUint32V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]uint32:
+		fastpathTV.EncMapUintptrUint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]uint64:
+		fastpathTV.EncMapUintptrUint64V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]uint64:
+		fastpathTV.EncMapUintptrUint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]uintptr:
+		fastpathTV.EncMapUintptrUintptrV(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]uintptr:
+		fastpathTV.EncMapUintptrUintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]int:
+		fastpathTV.EncMapUintptrIntV(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]int:
+		fastpathTV.EncMapUintptrIntV(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]int8:
+		fastpathTV.EncMapUintptrInt8V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]int8:
+		fastpathTV.EncMapUintptrInt8V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]int16:
+		fastpathTV.EncMapUintptrInt16V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]int16:
+		fastpathTV.EncMapUintptrInt16V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]int32:
+		fastpathTV.EncMapUintptrInt32V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]int32:
+		fastpathTV.EncMapUintptrInt32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]int64:
+		fastpathTV.EncMapUintptrInt64V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]int64:
+		fastpathTV.EncMapUintptrInt64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]float32:
+		fastpathTV.EncMapUintptrFloat32V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]float32:
+		fastpathTV.EncMapUintptrFloat32V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]float64:
+		fastpathTV.EncMapUintptrFloat64V(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]float64:
+		fastpathTV.EncMapUintptrFloat64V(*v, fastpathCheckNilTrue, e)
+
+	case map[uintptr]bool:
+		fastpathTV.EncMapUintptrBoolV(v, fastpathCheckNilTrue, e)
+	case *map[uintptr]bool:
+		fastpathTV.EncMapUintptrBoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[int]interface{}:
+		fastpathTV.EncMapIntIntfV(v, fastpathCheckNilTrue, e)
+	case *map[int]interface{}:
+		fastpathTV.EncMapIntIntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[int]string:
+		fastpathTV.EncMapIntStringV(v, fastpathCheckNilTrue, e)
+	case *map[int]string:
+		fastpathTV.EncMapIntStringV(*v, fastpathCheckNilTrue, e)
+
+	case map[int]uint:
+		fastpathTV.EncMapIntUintV(v, fastpathCheckNilTrue, e)
+	case *map[int]uint:
+		fastpathTV.EncMapIntUintV(*v, fastpathCheckNilTrue, e)
+
+	case map[int]uint8:
+		fastpathTV.EncMapIntUint8V(v, fastpathCheckNilTrue, e)
+	case *map[int]uint8:
+		fastpathTV.EncMapIntUint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]uint16:
+		fastpathTV.EncMapIntUint16V(v, fastpathCheckNilTrue, e)
+	case *map[int]uint16:
+		fastpathTV.EncMapIntUint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]uint32:
+		fastpathTV.EncMapIntUint32V(v, fastpathCheckNilTrue, e)
+	case *map[int]uint32:
+		fastpathTV.EncMapIntUint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]uint64:
+		fastpathTV.EncMapIntUint64V(v, fastpathCheckNilTrue, e)
+	case *map[int]uint64:
+		fastpathTV.EncMapIntUint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]uintptr:
+		fastpathTV.EncMapIntUintptrV(v, fastpathCheckNilTrue, e)
+	case *map[int]uintptr:
+		fastpathTV.EncMapIntUintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[int]int:
+		fastpathTV.EncMapIntIntV(v, fastpathCheckNilTrue, e)
+	case *map[int]int:
+		fastpathTV.EncMapIntIntV(*v, fastpathCheckNilTrue, e)
+
+	case map[int]int8:
+		fastpathTV.EncMapIntInt8V(v, fastpathCheckNilTrue, e)
+	case *map[int]int8:
+		fastpathTV.EncMapIntInt8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]int16:
+		fastpathTV.EncMapIntInt16V(v, fastpathCheckNilTrue, e)
+	case *map[int]int16:
+		fastpathTV.EncMapIntInt16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]int32:
+		fastpathTV.EncMapIntInt32V(v, fastpathCheckNilTrue, e)
+	case *map[int]int32:
+		fastpathTV.EncMapIntInt32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]int64:
+		fastpathTV.EncMapIntInt64V(v, fastpathCheckNilTrue, e)
+	case *map[int]int64:
+		fastpathTV.EncMapIntInt64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]float32:
+		fastpathTV.EncMapIntFloat32V(v, fastpathCheckNilTrue, e)
+	case *map[int]float32:
+		fastpathTV.EncMapIntFloat32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]float64:
+		fastpathTV.EncMapIntFloat64V(v, fastpathCheckNilTrue, e)
+	case *map[int]float64:
+		fastpathTV.EncMapIntFloat64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int]bool:
+		fastpathTV.EncMapIntBoolV(v, fastpathCheckNilTrue, e)
+	case *map[int]bool:
+		fastpathTV.EncMapIntBoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]interface{}:
+		fastpathTV.EncMapInt8IntfV(v, fastpathCheckNilTrue, e)
+	case *map[int8]interface{}:
+		fastpathTV.EncMapInt8IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]string:
+		fastpathTV.EncMapInt8StringV(v, fastpathCheckNilTrue, e)
+	case *map[int8]string:
+		fastpathTV.EncMapInt8StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]uint:
+		fastpathTV.EncMapInt8UintV(v, fastpathCheckNilTrue, e)
+	case *map[int8]uint:
+		fastpathTV.EncMapInt8UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]uint8:
+		fastpathTV.EncMapInt8Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[int8]uint8:
+		fastpathTV.EncMapInt8Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]uint16:
+		fastpathTV.EncMapInt8Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[int8]uint16:
+		fastpathTV.EncMapInt8Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]uint32:
+		fastpathTV.EncMapInt8Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[int8]uint32:
+		fastpathTV.EncMapInt8Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]uint64:
+		fastpathTV.EncMapInt8Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[int8]uint64:
+		fastpathTV.EncMapInt8Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]uintptr:
+		fastpathTV.EncMapInt8UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[int8]uintptr:
+		fastpathTV.EncMapInt8UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]int:
+		fastpathTV.EncMapInt8IntV(v, fastpathCheckNilTrue, e)
+	case *map[int8]int:
+		fastpathTV.EncMapInt8IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]int8:
+		fastpathTV.EncMapInt8Int8V(v, fastpathCheckNilTrue, e)
+	case *map[int8]int8:
+		fastpathTV.EncMapInt8Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]int16:
+		fastpathTV.EncMapInt8Int16V(v, fastpathCheckNilTrue, e)
+	case *map[int8]int16:
+		fastpathTV.EncMapInt8Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]int32:
+		fastpathTV.EncMapInt8Int32V(v, fastpathCheckNilTrue, e)
+	case *map[int8]int32:
+		fastpathTV.EncMapInt8Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]int64:
+		fastpathTV.EncMapInt8Int64V(v, fastpathCheckNilTrue, e)
+	case *map[int8]int64:
+		fastpathTV.EncMapInt8Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]float32:
+		fastpathTV.EncMapInt8Float32V(v, fastpathCheckNilTrue, e)
+	case *map[int8]float32:
+		fastpathTV.EncMapInt8Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]float64:
+		fastpathTV.EncMapInt8Float64V(v, fastpathCheckNilTrue, e)
+	case *map[int8]float64:
+		fastpathTV.EncMapInt8Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int8]bool:
+		fastpathTV.EncMapInt8BoolV(v, fastpathCheckNilTrue, e)
+	case *map[int8]bool:
+		fastpathTV.EncMapInt8BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]interface{}:
+		fastpathTV.EncMapInt16IntfV(v, fastpathCheckNilTrue, e)
+	case *map[int16]interface{}:
+		fastpathTV.EncMapInt16IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]string:
+		fastpathTV.EncMapInt16StringV(v, fastpathCheckNilTrue, e)
+	case *map[int16]string:
+		fastpathTV.EncMapInt16StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]uint:
+		fastpathTV.EncMapInt16UintV(v, fastpathCheckNilTrue, e)
+	case *map[int16]uint:
+		fastpathTV.EncMapInt16UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]uint8:
+		fastpathTV.EncMapInt16Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[int16]uint8:
+		fastpathTV.EncMapInt16Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]uint16:
+		fastpathTV.EncMapInt16Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[int16]uint16:
+		fastpathTV.EncMapInt16Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]uint32:
+		fastpathTV.EncMapInt16Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[int16]uint32:
+		fastpathTV.EncMapInt16Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]uint64:
+		fastpathTV.EncMapInt16Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[int16]uint64:
+		fastpathTV.EncMapInt16Uint64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]uintptr:
+		fastpathTV.EncMapInt16UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[int16]uintptr:
+		fastpathTV.EncMapInt16UintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]int:
+		fastpathTV.EncMapInt16IntV(v, fastpathCheckNilTrue, e)
+	case *map[int16]int:
+		fastpathTV.EncMapInt16IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]int8:
+		fastpathTV.EncMapInt16Int8V(v, fastpathCheckNilTrue, e)
+	case *map[int16]int8:
+		fastpathTV.EncMapInt16Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]int16:
+		fastpathTV.EncMapInt16Int16V(v, fastpathCheckNilTrue, e)
+	case *map[int16]int16:
+		fastpathTV.EncMapInt16Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]int32:
+		fastpathTV.EncMapInt16Int32V(v, fastpathCheckNilTrue, e)
+	case *map[int16]int32:
+		fastpathTV.EncMapInt16Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]int64:
+		fastpathTV.EncMapInt16Int64V(v, fastpathCheckNilTrue, e)
+	case *map[int16]int64:
+		fastpathTV.EncMapInt16Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]float32:
+		fastpathTV.EncMapInt16Float32V(v, fastpathCheckNilTrue, e)
+	case *map[int16]float32:
+		fastpathTV.EncMapInt16Float32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]float64:
+		fastpathTV.EncMapInt16Float64V(v, fastpathCheckNilTrue, e)
+	case *map[int16]float64:
+		fastpathTV.EncMapInt16Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int16]bool:
+		fastpathTV.EncMapInt16BoolV(v, fastpathCheckNilTrue, e)
+	case *map[int16]bool:
+		fastpathTV.EncMapInt16BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]interface{}:
+		fastpathTV.EncMapInt32IntfV(v, fastpathCheckNilTrue, e)
+	case *map[int32]interface{}:
+		fastpathTV.EncMapInt32IntfV(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]string:
+		fastpathTV.EncMapInt32StringV(v, fastpathCheckNilTrue, e)
+	case *map[int32]string:
+		fastpathTV.EncMapInt32StringV(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]uint:
+		fastpathTV.EncMapInt32UintV(v, fastpathCheckNilTrue, e)
+	case *map[int32]uint:
+		fastpathTV.EncMapInt32UintV(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]uint8:
+		fastpathTV.EncMapInt32Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[int32]uint8:
+		fastpathTV.EncMapInt32Uint8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]uint16:
+		fastpathTV.EncMapInt32Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[int32]uint16:
+		fastpathTV.EncMapInt32Uint16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]uint32:
+		fastpathTV.EncMapInt32Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[int32]uint32:
+		fastpathTV.EncMapInt32Uint32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]uint64:
+		fastpathTV.EncMapInt32Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[int32]uint64:
+		fastpathTV.EncMapInt32Uint64V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfStringV(rv2i(rv).(map[interface{}]string), e)
-}
-func (_ fastpathT) EncMapIntfStringV(v map[interface{}]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]uintptr:
+		fastpathTV.EncMapInt32UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[int32]uintptr:
+		fastpathTV.EncMapInt32UintptrV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUintV(rv2i(rv).(map[interface{}]uint), e)
-}
-func (_ fastpathT) EncMapIntfUintV(v map[interface{}]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]int:
+		fastpathTV.EncMapInt32IntV(v, fastpathCheckNilTrue, e)
+	case *map[int32]int:
+		fastpathTV.EncMapInt32IntV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint8V(rv2i(rv).(map[interface{}]uint8), e)
-}
-func (_ fastpathT) EncMapIntfUint8V(v map[interface{}]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]int8:
+		fastpathTV.EncMapInt32Int8V(v, fastpathCheckNilTrue, e)
+	case *map[int32]int8:
+		fastpathTV.EncMapInt32Int8V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint16V(rv2i(rv).(map[interface{}]uint16), e)
-}
-func (_ fastpathT) EncMapIntfUint16V(v map[interface{}]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]int16:
+		fastpathTV.EncMapInt32Int16V(v, fastpathCheckNilTrue, e)
+	case *map[int32]int16:
+		fastpathTV.EncMapInt32Int16V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint32V(rv2i(rv).(map[interface{}]uint32), e)
-}
-func (_ fastpathT) EncMapIntfUint32V(v map[interface{}]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]int32:
+		fastpathTV.EncMapInt32Int32V(v, fastpathCheckNilTrue, e)
+	case *map[int32]int32:
+		fastpathTV.EncMapInt32Int32V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint64V(rv2i(rv).(map[interface{}]uint64), e)
-}
-func (_ fastpathT) EncMapIntfUint64V(v map[interface{}]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]int64:
+		fastpathTV.EncMapInt32Int64V(v, fastpathCheckNilTrue, e)
+	case *map[int32]int64:
+		fastpathTV.EncMapInt32Int64V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUintptrV(rv2i(rv).(map[interface{}]uintptr), e)
-}
-func (_ fastpathT) EncMapIntfUintptrV(v map[interface{}]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]float32:
+		fastpathTV.EncMapInt32Float32V(v, fastpathCheckNilTrue, e)
+	case *map[int32]float32:
+		fastpathTV.EncMapInt32Float32V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfIntV(rv2i(rv).(map[interface{}]int), e)
-}
-func (_ fastpathT) EncMapIntfIntV(v map[interface{}]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int32]float64:
+		fastpathTV.EncMapInt32Float64V(v, fastpathCheckNilTrue, e)
+	case *map[int32]float64:
+		fastpathTV.EncMapInt32Float64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int32]bool:
+		fastpathTV.EncMapInt32BoolV(v, fastpathCheckNilTrue, e)
+	case *map[int32]bool:
+		fastpathTV.EncMapInt32BoolV(*v, fastpathCheckNilTrue, e)
+
+	case map[int64]interface{}:
+		fastpathTV.EncMapInt64IntfV(v, fastpathCheckNilTrue, e)
+	case *map[int64]interface{}:
+		fastpathTV.EncMapInt64IntfV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt8V(rv2i(rv).(map[interface{}]int8), e)
-}
-func (_ fastpathT) EncMapIntfInt8V(v map[interface{}]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]string:
+		fastpathTV.EncMapInt64StringV(v, fastpathCheckNilTrue, e)
+	case *map[int64]string:
+		fastpathTV.EncMapInt64StringV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt16V(rv2i(rv).(map[interface{}]int16), e)
-}
-func (_ fastpathT) EncMapIntfInt16V(v map[interface{}]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]uint:
+		fastpathTV.EncMapInt64UintV(v, fastpathCheckNilTrue, e)
+	case *map[int64]uint:
+		fastpathTV.EncMapInt64UintV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt32V(rv2i(rv).(map[interface{}]int32), e)
-}
-func (_ fastpathT) EncMapIntfInt32V(v map[interface{}]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]uint8:
+		fastpathTV.EncMapInt64Uint8V(v, fastpathCheckNilTrue, e)
+	case *map[int64]uint8:
+		fastpathTV.EncMapInt64Uint8V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt64V(rv2i(rv).(map[interface{}]int64), e)
-}
-func (_ fastpathT) EncMapIntfInt64V(v map[interface{}]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]uint16:
+		fastpathTV.EncMapInt64Uint16V(v, fastpathCheckNilTrue, e)
+	case *map[int64]uint16:
+		fastpathTV.EncMapInt64Uint16V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfFloat32V(rv2i(rv).(map[interface{}]float32), e)
-}
-func (_ fastpathT) EncMapIntfFloat32V(v map[interface{}]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]uint32:
+		fastpathTV.EncMapInt64Uint32V(v, fastpathCheckNilTrue, e)
+	case *map[int64]uint32:
+		fastpathTV.EncMapInt64Uint32V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfFloat64V(rv2i(rv).(map[interface{}]float64), e)
-}
-func (_ fastpathT) EncMapIntfFloat64V(v map[interface{}]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]uint64:
+		fastpathTV.EncMapInt64Uint64V(v, fastpathCheckNilTrue, e)
+	case *map[int64]uint64:
+		fastpathTV.EncMapInt64Uint64V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapIntfBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfBoolV(rv2i(rv).(map[interface{}]bool), e)
-}
-func (_ fastpathT) EncMapIntfBoolV(v map[interface{}]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]uintptr:
+		fastpathTV.EncMapInt64UintptrV(v, fastpathCheckNilTrue, e)
+	case *map[int64]uintptr:
+		fastpathTV.EncMapInt64UintptrV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringIntfV(rv2i(rv).(map[string]interface{}), e)
-}
-func (_ fastpathT) EncMapStringIntfV(v map[string]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]int:
+		fastpathTV.EncMapInt64IntV(v, fastpathCheckNilTrue, e)
+	case *map[int64]int:
+		fastpathTV.EncMapInt64IntV(*v, fastpathCheckNilTrue, e)
+
+	case map[int64]int8:
+		fastpathTV.EncMapInt64Int8V(v, fastpathCheckNilTrue, e)
+	case *map[int64]int8:
+		fastpathTV.EncMapInt64Int8V(*v, fastpathCheckNilTrue, e)
+
+	case map[int64]int16:
+		fastpathTV.EncMapInt64Int16V(v, fastpathCheckNilTrue, e)
+	case *map[int64]int16:
+		fastpathTV.EncMapInt64Int16V(*v, fastpathCheckNilTrue, e)
+
+	case map[int64]int32:
+		fastpathTV.EncMapInt64Int32V(v, fastpathCheckNilTrue, e)
+	case *map[int64]int32:
+		fastpathTV.EncMapInt64Int32V(*v, fastpathCheckNilTrue, e)
+
+	case map[int64]int64:
+		fastpathTV.EncMapInt64Int64V(v, fastpathCheckNilTrue, e)
+	case *map[int64]int64:
+		fastpathTV.EncMapInt64Int64V(*v, fastpathCheckNilTrue, e)
+
+	case map[int64]float32:
+		fastpathTV.EncMapInt64Float32V(v, fastpathCheckNilTrue, e)
+	case *map[int64]float32:
+		fastpathTV.EncMapInt64Float32V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringStringV(rv2i(rv).(map[string]string), e)
-}
-func (_ fastpathT) EncMapStringStringV(v map[string]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeString(cUTF8, v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]float64:
+		fastpathTV.EncMapInt64Float64V(v, fastpathCheckNilTrue, e)
+	case *map[int64]float64:
+		fastpathTV.EncMapInt64Float64V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUintV(rv2i(rv).(map[string]uint), e)
-}
-func (_ fastpathT) EncMapStringUintV(v map[string]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[int64]bool:
+		fastpathTV.EncMapInt64BoolV(v, fastpathCheckNilTrue, e)
+	case *map[int64]bool:
+		fastpathTV.EncMapInt64BoolV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint8V(rv2i(rv).(map[string]uint8), e)
-}
-func (_ fastpathT) EncMapStringUint8V(v map[string]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[bool]interface{}:
+		fastpathTV.EncMapBoolIntfV(v, fastpathCheckNilTrue, e)
+	case *map[bool]interface{}:
+		fastpathTV.EncMapBoolIntfV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint16V(rv2i(rv).(map[string]uint16), e)
-}
-func (_ fastpathT) EncMapStringUint16V(v map[string]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[bool]string:
+		fastpathTV.EncMapBoolStringV(v, fastpathCheckNilTrue, e)
+	case *map[bool]string:
+		fastpathTV.EncMapBoolStringV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint32V(rv2i(rv).(map[string]uint32), e)
-}
-func (_ fastpathT) EncMapStringUint32V(v map[string]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[bool]uint:
+		fastpathTV.EncMapBoolUintV(v, fastpathCheckNilTrue, e)
+	case *map[bool]uint:
+		fastpathTV.EncMapBoolUintV(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint64V(rv2i(rv).(map[string]uint64), e)
-}
-func (_ fastpathT) EncMapStringUint64V(v map[string]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[bool]uint8:
+		fastpathTV.EncMapBoolUint8V(v, fastpathCheckNilTrue, e)
+	case *map[bool]uint8:
+		fastpathTV.EncMapBoolUint8V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUintptrV(rv2i(rv).(map[string]uintptr), e)
-}
-func (_ fastpathT) EncMapStringUintptrV(v map[string]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[bool]uint16:
+		fastpathTV.EncMapBoolUint16V(v, fastpathCheckNilTrue, e)
+	case *map[bool]uint16:
+		fastpathTV.EncMapBoolUint16V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringIntV(rv2i(rv).(map[string]int), e)
-}
-func (_ fastpathT) EncMapStringIntV(v map[string]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[bool]uint32:
+		fastpathTV.EncMapBoolUint32V(v, fastpathCheckNilTrue, e)
+	case *map[bool]uint32:
+		fastpathTV.EncMapBoolUint32V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt8V(rv2i(rv).(map[string]int8), e)
-}
-func (_ fastpathT) EncMapStringInt8V(v map[string]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
+	case map[bool]uint64:
+		fastpathTV.EncMapBoolUint64V(v, fastpathCheckNilTrue, e)
+	case *map[bool]uint64:
+		fastpathTV.EncMapBoolUint64V(*v, fastpathCheckNilTrue, e)
 
-func (e *Encoder) fastpathEncMapStringInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt16V(rv2i(rv).(map[string]int16), e)
-}
-func (_ fastpathT) EncMapStringInt16V(v map[string]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
+	case map[bool]uintptr:
+		fastpathTV.EncMapBoolUintptrV(v, fastpathCheckNilTrue, e)
+	case *map[bool]uintptr:
+		fastpathTV.EncMapBoolUintptrV(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]int:
+		fastpathTV.EncMapBoolIntV(v, fastpathCheckNilTrue, e)
+	case *map[bool]int:
+		fastpathTV.EncMapBoolIntV(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]int8:
+		fastpathTV.EncMapBoolInt8V(v, fastpathCheckNilTrue, e)
+	case *map[bool]int8:
+		fastpathTV.EncMapBoolInt8V(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]int16:
+		fastpathTV.EncMapBoolInt16V(v, fastpathCheckNilTrue, e)
+	case *map[bool]int16:
+		fastpathTV.EncMapBoolInt16V(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]int32:
+		fastpathTV.EncMapBoolInt32V(v, fastpathCheckNilTrue, e)
+	case *map[bool]int32:
+		fastpathTV.EncMapBoolInt32V(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]int64:
+		fastpathTV.EncMapBoolInt64V(v, fastpathCheckNilTrue, e)
+	case *map[bool]int64:
+		fastpathTV.EncMapBoolInt64V(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]float32:
+		fastpathTV.EncMapBoolFloat32V(v, fastpathCheckNilTrue, e)
+	case *map[bool]float32:
+		fastpathTV.EncMapBoolFloat32V(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]float64:
+		fastpathTV.EncMapBoolFloat64V(v, fastpathCheckNilTrue, e)
+	case *map[bool]float64:
+		fastpathTV.EncMapBoolFloat64V(*v, fastpathCheckNilTrue, e)
+
+	case map[bool]bool:
+		fastpathTV.EncMapBoolBoolV(v, fastpathCheckNilTrue, e)
+	case *map[bool]bool:
+		fastpathTV.EncMapBoolBoolV(*v, fastpathCheckNilTrue, e)
+
+	default:
+		_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
+		return false
 	}
-	ee.WriteMapEnd()
+	return true
 }
 
-func (e *Encoder) fastpathEncMapStringInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt32V(rv2i(rv).(map[string]int32), e)
-}
-func (_ fastpathT) EncMapStringInt32V(v map[string]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
+// -- -- fast path functions
+
+func (f *encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e)
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
+		fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e)
 	}
-	ee.WriteMapEnd()
 }
-
-func (e *Encoder) fastpathEncMapStringInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt64V(rv2i(rv).(map[string]int64), e)
-}
-func (_ fastpathT) EncMapStringInt64V(v map[string]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		e.encode(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapStringFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringFloat32V(rv2i(rv).(map[string]float32), e)
-}
-func (_ fastpathT) EncMapStringFloat32V(v map[string]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat32(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringFloat64V(rv2i(rv).(map[string]float64), e)
-}
-func (_ fastpathT) EncMapStringFloat64V(v map[string]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat64(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat64(v2)
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		e.encode(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapStringBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringBoolV(rv2i(rv).(map[string]bool), e)
-}
-func (_ fastpathT) EncMapStringBoolV(v map[string]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeBool(v[string(k2)])
-			}
-		}
+func (f *encFnInfo) fastpathEncSliceStringR(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e)
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeBool(v2)
-			}
-		}
+		fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e)
 	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32IntfV(rv2i(rv).(map[float32]interface{}), e)
 }
-func (_ fastpathT) EncMapFloat32IntfV(v map[float32]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				e.encode(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				e.encode(v2)
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeString(c_UTF8, v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32StringV(rv2i(rv).(map[float32]string), e)
-}
-func (_ fastpathT) EncMapFloat32StringV(v map[float32]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceStringV(v []string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeString(cUTF8, v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32UintV(rv2i(rv).(map[float32]uint), e)
-}
-func (_ fastpathT) EncMapFloat32UintV(v map[float32]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeString(c_UTF8, v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint8V(rv2i(rv).(map[float32]uint8), e)
+func (f *encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat32Uint8V(v map[float32]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeFloat32(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint16V(rv2i(rv).(map[float32]uint16), e)
-}
-func (_ fastpathT) EncMapFloat32Uint16V(v map[float32]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeFloat32(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint32V(rv2i(rv).(map[float32]uint32), e)
+func (f *encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat32Uint32V(v map[float32]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeFloat64(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint64V(rv2i(rv).(map[float32]uint64), e)
-}
-func (_ fastpathT) EncMapFloat32Uint64V(v map[float32]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeFloat64(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32UintptrV(rv2i(rv).(map[float32]uintptr), e)
+func (f *encFnInfo) fastpathEncSliceUintR(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat32UintptrV(v map[float32]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				e.encode(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				e.encode(v2)
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32IntV(rv2i(rv).(map[float32]int), e)
-}
-func (_ fastpathT) EncMapFloat32IntV(v map[float32]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceUintV(v []uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int8V(rv2i(rv).(map[float32]int8), e)
+func (f *encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat32Int8V(v map[float32]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int16V(rv2i(rv).(map[float32]int16), e)
-}
-func (_ fastpathT) EncMapFloat32Int16V(v map[float32]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int32V(rv2i(rv).(map[float32]int32), e)
+func (f *encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat32Int32V(v map[float32]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int64V(rv2i(rv).(map[float32]int64), e)
-}
-func (_ fastpathT) EncMapFloat32Int64V(v map[float32]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Float32V(rv2i(rv).(map[float32]float32), e)
+func (f *encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat32Float32V(v map[float32]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeFloat32(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeFloat32(v2)
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Float64V(rv2i(rv).(map[float32]float64), e)
-}
-func (_ fastpathT) EncMapFloat32Float64V(v map[float32]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeFloat64(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeFloat64(v2)
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeUint(uint64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat32BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32BoolV(rv2i(rv).(map[float32]bool), e)
+func (f *encFnInfo) fastpathEncSliceUintptrR(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat32BoolV(v map[float32]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeBool(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeBool(v2)
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		e.encode(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64IntfV(rv2i(rv).(map[float64]interface{}), e)
-}
-func (_ fastpathT) EncMapFloat64IntfV(v map[float64]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				e.encode(v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				e.encode(v2)
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		e.encode(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64StringV(rv2i(rv).(map[float64]string), e)
+func (f *encFnInfo) fastpathEncSliceIntR(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat64StringV(v map[float64]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeString(cUTF8, v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64UintV(rv2i(rv).(map[float64]uint), e)
-}
-func (_ fastpathT) EncMapFloat64UintV(v map[float64]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceIntV(v []int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint8V(rv2i(rv).(map[float64]uint8), e)
+func (f *encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat64Uint8V(v map[float64]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint16V(rv2i(rv).(map[float64]uint16), e)
-}
-func (_ fastpathT) EncMapFloat64Uint16V(v map[float64]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceInt8V(v []int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint32V(rv2i(rv).(map[float64]uint32), e)
+func (f *encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat64Uint32V(v map[float64]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint64V(rv2i(rv).(map[float64]uint64), e)
-}
-func (_ fastpathT) EncMapFloat64Uint64V(v map[float64]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceInt16V(v []int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64UintptrV(rv2i(rv).(map[float64]uintptr), e)
+func (f *encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat64UintptrV(v map[float64]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				e.encode(v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				e.encode(v2)
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64IntV(rv2i(rv).(map[float64]int), e)
-}
-func (_ fastpathT) EncMapFloat64IntV(v map[float64]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceInt32V(v []int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int8V(rv2i(rv).(map[float64]int8), e)
+func (f *encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat64Int8V(v map[float64]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int16V(rv2i(rv).(map[float64]int16), e)
-}
-func (_ fastpathT) EncMapFloat64Int16V(v map[float64]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncAsMapSliceInt64V(v []int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeInt(int64(v2))
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int32V(rv2i(rv).(map[float64]int32), e)
+func (f *encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e)
+	}
 }
-func (_ fastpathT) EncMapFloat64Int32V(v map[float64]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil {
+			cr.sendContainerState(containerArrayElem)
 		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
+		ee.EncodeBool(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerArrayEnd)
+	}
+}
+
+func (_ fastpathT) EncAsMapSliceBoolV(v []bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
 			}
 		}
+		ee.EncodeBool(v2)
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
 	}
-	ee.WriteMapEnd()
 }
 
-func (e *Encoder) fastpathEncMapFloat64Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int64V(rv2i(rv).(map[float64]int64), e)
+func (f *encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) {
+	fastpathTV.EncMapIntfIntfV(rv.Interface().(map[interface{}]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapFloat64Int64V(v map[float64]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapFloat64Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Float32V(rv2i(rv).(map[float64]float32), e)
+func (f *encFnInfo) fastpathEncMapIntfStringR(rv reflect.Value) {
+	fastpathTV.EncMapIntfStringV(rv.Interface().(map[interface{}]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapFloat64Float32V(v map[float64]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfStringV(v map[interface{}]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[float64(k2)])
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeFloat32(v[float64(k2)])
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeFloat32(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapFloat64Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Float64V(rv2i(rv).(map[float64]float64), e)
+func (f *encFnInfo) fastpathEncMapIntfUintR(rv reflect.Value) {
+	fastpathTV.EncMapIntfUintV(rv.Interface().(map[interface{}]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapFloat64Float64V(v map[float64]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
+func (_ fastpathT) EncMapIntfUintV(v map[interface{}]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[float64(k2)])
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeFloat64(v[float64(k2)])
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeFloat64(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapFloat64BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64BoolV(rv2i(rv).(map[float64]bool), e)
+func (f *encFnInfo) fastpathEncMapIntfUint8R(rv reflect.Value) {
+	fastpathTV.EncMapIntfUint8V(rv.Interface().(map[interface{}]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapFloat64BoolV(v map[float64]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfUint8V(v map[interface{}]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[float64(k2)])
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeBool(v[float64(k2)])
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeBool(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintIntfV(rv2i(rv).(map[uint]interface{}), e)
+func (f *encFnInfo) fastpathEncMapIntfUint16R(rv reflect.Value) {
+	fastpathTV.EncMapIntfUint16V(rv.Interface().(map[interface{}]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintIntfV(v map[uint]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfUint16V(v map[interface{}]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint(k2)])
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				e.encode(v[uint(k2)])
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintStringV(rv2i(rv).(map[uint]string), e)
+func (f *encFnInfo) fastpathEncMapIntfUint32R(rv reflect.Value) {
+	fastpathTV.EncMapIntfUint32V(rv.Interface().(map[interface{}]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintStringV(v map[uint]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfUint32V(v map[interface{}]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint(k2)])
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeString(cUTF8, v[uint(k2)])
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUintV(rv2i(rv).(map[uint]uint), e)
+func (f *encFnInfo) fastpathEncMapIntfUint64R(rv reflect.Value) {
+	fastpathTV.EncMapIntfUint64V(rv.Interface().(map[interface{}]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintUintV(v map[uint]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfUint64V(v map[interface{}]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint8V(rv2i(rv).(map[uint]uint8), e)
+func (f *encFnInfo) fastpathEncMapIntfUintptrR(rv reflect.Value) {
+	fastpathTV.EncMapIntfUintptrV(rv.Interface().(map[interface{}]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintUint8V(v map[uint]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfUintptrV(v map[interface{}]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint16V(rv2i(rv).(map[uint]uint16), e)
+func (f *encFnInfo) fastpathEncMapIntfIntR(rv reflect.Value) {
+	fastpathTV.EncMapIntfIntV(rv.Interface().(map[interface{}]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintUint16V(v map[uint]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfIntV(v map[interface{}]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint32V(rv2i(rv).(map[uint]uint32), e)
+func (f *encFnInfo) fastpathEncMapIntfInt8R(rv reflect.Value) {
+	fastpathTV.EncMapIntfInt8V(rv.Interface().(map[interface{}]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintUint32V(v map[uint]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfInt8V(v map[interface{}]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint64V(rv2i(rv).(map[uint]uint64), e)
+func (f *encFnInfo) fastpathEncMapIntfInt16R(rv reflect.Value) {
+	fastpathTV.EncMapIntfInt16V(rv.Interface().(map[interface{}]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintUint64V(v map[uint]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfInt16V(v map[interface{}]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUintptrV(rv2i(rv).(map[uint]uintptr), e)
+func (f *encFnInfo) fastpathEncMapIntfInt32R(rv reflect.Value) {
+	fastpathTV.EncMapIntfInt32V(rv.Interface().(map[interface{}]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintUintptrV(v map[uint]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfInt32V(v map[interface{}]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint(k2)])
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				e.encode(v[uint(k2)])
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintIntV(rv2i(rv).(map[uint]int), e)
+func (f *encFnInfo) fastpathEncMapIntfInt64R(rv reflect.Value) {
+	fastpathTV.EncMapIntfInt64V(rv.Interface().(map[interface{}]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintIntV(v map[uint]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfInt64V(v map[interface{}]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt8V(rv2i(rv).(map[uint]int8), e)
+func (f *encFnInfo) fastpathEncMapIntfFloat32R(rv reflect.Value) {
+	fastpathTV.EncMapIntfFloat32V(rv.Interface().(map[interface{}]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintInt8V(v map[uint]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfFloat32V(v map[interface{}]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt16V(rv2i(rv).(map[uint]int16), e)
+func (f *encFnInfo) fastpathEncMapIntfFloat64R(rv reflect.Value) {
+	fastpathTV.EncMapIntfFloat64V(rv.Interface().(map[interface{}]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintInt16V(v map[uint]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfFloat64V(v map[interface{}]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt32V(rv2i(rv).(map[uint]int32), e)
+func (f *encFnInfo) fastpathEncMapIntfBoolR(rv reflect.Value) {
+	fastpathTV.EncMapIntfBoolV(rv.Interface().(map[interface{}]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintInt32V(v map[uint]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntfBoolV(v map[interface{}]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
+			e.asis(v2[j].v)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[v2[j].i])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt64V(rv2i(rv).(map[uint]int64), e)
+func (f *encFnInfo) fastpathEncMapStringIntfR(rv reflect.Value) {
+	fastpathTV.EncMapStringIntfV(rv.Interface().(map[string]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintInt64V(v map[uint]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringIntfV(v map[string]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[string(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintFloat32V(rv2i(rv).(map[uint]float32), e)
+func (f *encFnInfo) fastpathEncMapStringStringR(rv reflect.Value) {
+	fastpathTV.EncMapStringStringV(rv.Interface().(map[string]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintFloat32V(v map[uint]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringStringV(v map[string]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint(k2)])
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeFloat32(v[uint(k2)])
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[string(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintFloat64V(rv2i(rv).(map[uint]float64), e)
+func (f *encFnInfo) fastpathEncMapStringUintR(rv reflect.Value) {
+	fastpathTV.EncMapStringUintV(rv.Interface().(map[string]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintFloat64V(v map[uint]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringUintV(v map[string]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint(k2)])
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeFloat64(v[uint(k2)])
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintBoolV(rv2i(rv).(map[uint]bool), e)
+func (f *encFnInfo) fastpathEncMapStringUint8R(rv reflect.Value) {
+	fastpathTV.EncMapStringUint8V(rv.Interface().(map[string]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintBoolV(v map[uint]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringUint8V(v map[string]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint(k2)])
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeBool(v[uint(k2)])
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8IntfV(rv2i(rv).(map[uint8]interface{}), e)
+func (f *encFnInfo) fastpathEncMapStringUint16R(rv reflect.Value) {
+	fastpathTV.EncMapStringUint16V(rv.Interface().(map[string]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8IntfV(v map[uint8]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringUint16V(v map[string]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint8(k2)])
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				e.encode(v[uint8(k2)])
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8StringV(rv2i(rv).(map[uint8]string), e)
+func (f *encFnInfo) fastpathEncMapStringUint32R(rv reflect.Value) {
+	fastpathTV.EncMapStringUint32V(rv.Interface().(map[string]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8StringV(v map[uint8]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringUint32V(v map[string]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint8(k2)])
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeString(cUTF8, v[uint8(k2)])
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8UintV(rv2i(rv).(map[uint8]uint), e)
+func (f *encFnInfo) fastpathEncMapStringUint64R(rv reflect.Value) {
+	fastpathTV.EncMapStringUint64V(rv.Interface().(map[string]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8UintV(v map[uint8]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringUint64V(v map[string]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint8V(rv2i(rv).(map[uint8]uint8), e)
+func (f *encFnInfo) fastpathEncMapStringUintptrR(rv reflect.Value) {
+	fastpathTV.EncMapStringUintptrV(rv.Interface().(map[string]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Uint8V(v map[uint8]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringUintptrV(v map[string]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[string(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint16V(rv2i(rv).(map[uint8]uint16), e)
+func (f *encFnInfo) fastpathEncMapStringIntR(rv reflect.Value) {
+	fastpathTV.EncMapStringIntV(rv.Interface().(map[string]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Uint16V(v map[uint8]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringIntV(v map[string]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint32V(rv2i(rv).(map[uint8]uint32), e)
+func (f *encFnInfo) fastpathEncMapStringInt8R(rv reflect.Value) {
+	fastpathTV.EncMapStringInt8V(rv.Interface().(map[string]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Uint32V(v map[uint8]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringInt8V(v map[string]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint64V(rv2i(rv).(map[uint8]uint64), e)
+func (f *encFnInfo) fastpathEncMapStringInt16R(rv reflect.Value) {
+	fastpathTV.EncMapStringInt16V(rv.Interface().(map[string]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Uint64V(v map[uint8]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringInt16V(v map[string]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8UintptrV(rv2i(rv).(map[uint8]uintptr), e)
+func (f *encFnInfo) fastpathEncMapStringInt32R(rv reflect.Value) {
+	fastpathTV.EncMapStringInt32V(rv.Interface().(map[string]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8UintptrV(v map[uint8]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringInt32V(v map[string]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint8(k2)])
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				e.encode(v[uint8(k2)])
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8IntV(rv2i(rv).(map[uint8]int), e)
+func (f *encFnInfo) fastpathEncMapStringInt64R(rv reflect.Value) {
+	fastpathTV.EncMapStringInt64V(rv.Interface().(map[string]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8IntV(v map[uint8]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringInt64V(v map[string]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[string(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int8V(rv2i(rv).(map[uint8]int8), e)
+func (f *encFnInfo) fastpathEncMapStringFloat32R(rv reflect.Value) {
+	fastpathTV.EncMapStringFloat32V(rv.Interface().(map[string]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Int8V(v map[uint8]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringFloat32V(v map[string]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v[string(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int16V(rv2i(rv).(map[uint8]int16), e)
+func (f *encFnInfo) fastpathEncMapStringFloat64R(rv reflect.Value) {
+	fastpathTV.EncMapStringFloat64V(rv.Interface().(map[string]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Int16V(v map[uint8]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringFloat64V(v map[string]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v[string(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int32V(rv2i(rv).(map[uint8]int32), e)
+func (f *encFnInfo) fastpathEncMapStringBoolR(rv reflect.Value) {
+	fastpathTV.EncMapStringBoolV(rv.Interface().(map[string]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Int32V(v map[uint8]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapStringBoolV(v map[string]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
+	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]string, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = string(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
+		sort.Sort(stringSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[string(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int64V(rv2i(rv).(map[uint8]int64), e)
+func (f *encFnInfo) fastpathEncMapFloat32IntfR(rv reflect.Value) {
+	fastpathTV.EncMapFloat32IntfV(rv.Interface().(map[float32]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Int64V(v map[uint8]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32IntfV(v map[float32]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[float32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Float32V(rv2i(rv).(map[uint8]float32), e)
+func (f *encFnInfo) fastpathEncMapFloat32StringR(rv reflect.Value) {
+	fastpathTV.EncMapFloat32StringV(rv.Interface().(map[float32]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Float32V(v map[uint8]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32StringV(v map[float32]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint8(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeFloat32(v[uint8(k2)])
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[float32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Float64V(rv2i(rv).(map[uint8]float64), e)
+func (f *encFnInfo) fastpathEncMapFloat32UintR(rv reflect.Value) {
+	fastpathTV.EncMapFloat32UintV(rv.Interface().(map[float32]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8Float64V(v map[uint8]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32UintV(v map[float32]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint8(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeFloat64(v[uint8(k2)])
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint8BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8BoolV(rv2i(rv).(map[uint8]bool), e)
+func (f *encFnInfo) fastpathEncMapFloat32Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint8V(rv.Interface().(map[float32]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint8BoolV(v map[uint8]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Uint8V(v map[float32]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint8(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeBool(v[uint8(k2)])
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16IntfV(rv2i(rv).(map[uint16]interface{}), e)
+func (f *encFnInfo) fastpathEncMapFloat32Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint16V(rv.Interface().(map[float32]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16IntfV(v map[uint16]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Uint16V(v map[float32]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint16(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				e.encode(v[uint16(k2)])
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16StringV(rv2i(rv).(map[uint16]string), e)
+func (f *encFnInfo) fastpathEncMapFloat32Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint32V(rv.Interface().(map[float32]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16StringV(v map[uint16]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Uint32V(v map[float32]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint16(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeString(cUTF8, v[uint16(k2)])
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16UintV(rv2i(rv).(map[uint16]uint), e)
+func (f *encFnInfo) fastpathEncMapFloat32Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint64V(rv.Interface().(map[float32]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16UintV(v map[uint16]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Uint64V(v map[float32]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint8V(rv2i(rv).(map[uint16]uint8), e)
+func (f *encFnInfo) fastpathEncMapFloat32UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapFloat32UintptrV(rv.Interface().(map[float32]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Uint8V(v map[uint16]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32UintptrV(v map[float32]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[float32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint16V(rv2i(rv).(map[uint16]uint16), e)
+func (f *encFnInfo) fastpathEncMapFloat32IntR(rv reflect.Value) {
+	fastpathTV.EncMapFloat32IntV(rv.Interface().(map[float32]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Uint16V(v map[uint16]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32IntV(v map[float32]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint32V(rv2i(rv).(map[uint16]uint32), e)
+func (f *encFnInfo) fastpathEncMapFloat32Int8R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int8V(rv.Interface().(map[float32]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Uint32V(v map[uint16]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Int8V(v map[float32]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint64V(rv2i(rv).(map[uint16]uint64), e)
+func (f *encFnInfo) fastpathEncMapFloat32Int16R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int16V(rv.Interface().(map[float32]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Uint64V(v map[uint16]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Int16V(v map[float32]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16UintptrV(rv2i(rv).(map[uint16]uintptr), e)
+func (f *encFnInfo) fastpathEncMapFloat32Int32R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int32V(rv.Interface().(map[float32]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16UintptrV(v map[uint16]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Int32V(v map[float32]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint16(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				e.encode(v[uint16(k2)])
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16IntV(rv2i(rv).(map[uint16]int), e)
+func (f *encFnInfo) fastpathEncMapFloat32Int64R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int64V(rv.Interface().(map[float32]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16IntV(v map[uint16]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Int64V(v map[float32]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int8V(rv2i(rv).(map[uint16]int8), e)
+func (f *encFnInfo) fastpathEncMapFloat32Float32R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Float32V(rv.Interface().(map[float32]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Int8V(v map[uint16]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Float32V(v map[float32]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[float32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int16V(rv2i(rv).(map[uint16]int16), e)
+func (f *encFnInfo) fastpathEncMapFloat32Float64R(rv reflect.Value) {
+	fastpathTV.EncMapFloat32Float64V(rv.Interface().(map[float32]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Int16V(v map[uint16]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32Float64V(v map[float32]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[float32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int32V(rv2i(rv).(map[uint16]int32), e)
+func (f *encFnInfo) fastpathEncMapFloat32BoolR(rv reflect.Value) {
+	fastpathTV.EncMapFloat32BoolV(rv.Interface().(map[float32]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Int32V(v map[uint16]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat32BoolV(v map[float32]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
+			ee.EncodeFloat32(float32(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[float32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat32(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int64V(rv2i(rv).(map[uint16]int64), e)
+func (f *encFnInfo) fastpathEncMapFloat64IntfR(rv reflect.Value) {
+	fastpathTV.EncMapFloat64IntfV(rv.Interface().(map[float64]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Int64V(v map[uint16]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64IntfV(v map[float64]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[float64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Float32V(rv2i(rv).(map[uint16]float32), e)
+func (f *encFnInfo) fastpathEncMapFloat64StringR(rv reflect.Value) {
+	fastpathTV.EncMapFloat64StringV(rv.Interface().(map[float64]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Float32V(v map[uint16]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64StringV(v map[float64]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint16(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeFloat32(v[uint16(k2)])
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[float64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Float64V(rv2i(rv).(map[uint16]float64), e)
+func (f *encFnInfo) fastpathEncMapFloat64UintR(rv reflect.Value) {
+	fastpathTV.EncMapFloat64UintV(rv.Interface().(map[float64]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16Float64V(v map[uint16]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64UintV(v map[float64]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint16(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeFloat64(v[uint16(k2)])
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint16BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16BoolV(rv2i(rv).(map[uint16]bool), e)
+func (f *encFnInfo) fastpathEncMapFloat64Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint8V(rv.Interface().(map[float64]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint16BoolV(v map[uint16]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Uint8V(v map[float64]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint16(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeBool(v[uint16(k2)])
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32IntfV(rv2i(rv).(map[uint32]interface{}), e)
+func (f *encFnInfo) fastpathEncMapFloat64Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint16V(rv.Interface().(map[float64]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32IntfV(v map[uint32]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Uint16V(v map[float64]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint32(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				e.encode(v[uint32(k2)])
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32StringV(rv2i(rv).(map[uint32]string), e)
+func (f *encFnInfo) fastpathEncMapFloat64Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint32V(rv.Interface().(map[float64]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32StringV(v map[uint32]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Uint32V(v map[float64]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint32(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeString(cUTF8, v[uint32(k2)])
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32UintV(rv2i(rv).(map[uint32]uint), e)
+func (f *encFnInfo) fastpathEncMapFloat64Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint64V(rv.Interface().(map[float64]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32UintV(v map[uint32]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Uint64V(v map[float64]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint8V(rv2i(rv).(map[uint32]uint8), e)
+func (f *encFnInfo) fastpathEncMapFloat64UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapFloat64UintptrV(rv.Interface().(map[float64]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Uint8V(v map[uint32]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64UintptrV(v map[float64]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[float64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint16V(rv2i(rv).(map[uint32]uint16), e)
+func (f *encFnInfo) fastpathEncMapFloat64IntR(rv reflect.Value) {
+	fastpathTV.EncMapFloat64IntV(rv.Interface().(map[float64]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Uint16V(v map[uint32]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64IntV(v map[float64]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint32V(rv2i(rv).(map[uint32]uint32), e)
+func (f *encFnInfo) fastpathEncMapFloat64Int8R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int8V(rv.Interface().(map[float64]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Uint32V(v map[uint32]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Int8V(v map[float64]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint64V(rv2i(rv).(map[uint32]uint64), e)
+func (f *encFnInfo) fastpathEncMapFloat64Int16R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int16V(rv.Interface().(map[float64]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Uint64V(v map[uint32]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Int16V(v map[float64]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32UintptrV(rv2i(rv).(map[uint32]uintptr), e)
+func (f *encFnInfo) fastpathEncMapFloat64Int32R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int32V(rv.Interface().(map[float64]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32UintptrV(v map[uint32]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Int32V(v map[float64]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint32(k2)])
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				e.encode(v[uint32(k2)])
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32IntV(rv2i(rv).(map[uint32]int), e)
+func (f *encFnInfo) fastpathEncMapFloat64Int64R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int64V(rv.Interface().(map[float64]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32IntV(v map[uint32]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Int64V(v map[float64]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[float64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int8V(rv2i(rv).(map[uint32]int8), e)
+func (f *encFnInfo) fastpathEncMapFloat64Float32R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Float32V(rv.Interface().(map[float64]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Int8V(v map[uint32]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Float32V(v map[float64]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[float64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int16V(rv2i(rv).(map[uint32]int16), e)
+func (f *encFnInfo) fastpathEncMapFloat64Float64R(rv reflect.Value) {
+	fastpathTV.EncMapFloat64Float64V(rv.Interface().(map[float64]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Int16V(v map[uint32]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64Float64V(v map[float64]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[float64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int32V(rv2i(rv).(map[uint32]int32), e)
+func (f *encFnInfo) fastpathEncMapFloat64BoolR(rv reflect.Value) {
+	fastpathTV.EncMapFloat64BoolV(rv.Interface().(map[float64]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Int32V(v map[uint32]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapFloat64BoolV(v map[float64]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
+		v2 := make([]float64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = uint64(k)
+			v2[i] = float64(k)
 			i++
 		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
+		sort.Sort(floatSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
+			ee.EncodeFloat64(float64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[float64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeFloat64(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int64V(rv2i(rv).(map[uint32]int64), e)
+func (f *encFnInfo) fastpathEncMapUintIntfR(rv reflect.Value) {
+	fastpathTV.EncMapUintIntfV(rv.Interface().(map[uint]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintIntfV(v map[uint]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8471,47 +7127,44 @@ func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Float32V(rv2i(rv).(map[uint32]float32), e)
+func (f *encFnInfo) fastpathEncMapUintStringR(rv reflect.Value) {
+	fastpathTV.EncMapUintStringV(rv.Interface().(map[uint]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintStringV(v map[uint]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8520,47 +7173,44 @@ func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint32(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeFloat32(v[uint32(k2)])
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[uint(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Float64V(rv2i(rv).(map[uint32]float64), e)
+func (f *encFnInfo) fastpathEncMapUintUintR(rv reflect.Value) {
+	fastpathTV.EncMapUintUintV(rv.Interface().(map[uint]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintUintV(v map[uint]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8569,47 +7219,44 @@ func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint32(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeFloat64(v[uint32(k2)])
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint32BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32BoolV(rv2i(rv).(map[uint32]bool), e)
+func (f *encFnInfo) fastpathEncMapUintUint8R(rv reflect.Value) {
+	fastpathTV.EncMapUintUint8V(rv.Interface().(map[uint]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintUint8V(v map[uint]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8618,47 +7265,44 @@ func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint32(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeBool(v[uint32(k2)])
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64IntfV(rv2i(rv).(map[uint64]interface{}), e)
+func (f *encFnInfo) fastpathEncMapUintUint16R(rv reflect.Value) {
+	fastpathTV.EncMapUintUint16V(rv.Interface().(map[uint]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintUint16V(v map[uint]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8667,47 +7311,44 @@ func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				e.encode(v[uint64(k2)])
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64StringV(rv2i(rv).(map[uint64]string), e)
+func (f *encFnInfo) fastpathEncMapUintUint32R(rv reflect.Value) {
+	fastpathTV.EncMapUintUint32V(rv.Interface().(map[uint]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintUint32V(v map[uint]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8716,47 +7357,44 @@ func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeString(cUTF8, v[uint64(k2)])
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64UintV(rv2i(rv).(map[uint64]uint), e)
+func (f *encFnInfo) fastpathEncMapUintUint64R(rv reflect.Value) {
+	fastpathTV.EncMapUintUint64V(rv.Interface().(map[uint]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintUint64V(v map[uint]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8765,47 +7403,44 @@ func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint8V(rv2i(rv).(map[uint64]uint8), e)
+func (f *encFnInfo) fastpathEncMapUintUintptrR(rv reflect.Value) {
+	fastpathTV.EncMapUintUintptrV(rv.Interface().(map[uint]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintUintptrV(v map[uint]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8814,47 +7449,44 @@ func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint16V(rv2i(rv).(map[uint64]uint16), e)
+func (f *encFnInfo) fastpathEncMapUintIntR(rv reflect.Value) {
+	fastpathTV.EncMapUintIntV(rv.Interface().(map[uint]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintIntV(v map[uint]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8863,47 +7495,44 @@ func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint32V(rv2i(rv).(map[uint64]uint32), e)
+func (f *encFnInfo) fastpathEncMapUintInt8R(rv reflect.Value) {
+	fastpathTV.EncMapUintInt8V(rv.Interface().(map[uint]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintInt8V(v map[uint]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8912,47 +7541,44 @@ func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint64V(rv2i(rv).(map[uint64]uint64), e)
+func (f *encFnInfo) fastpathEncMapUintInt16R(rv reflect.Value) {
+	fastpathTV.EncMapUintInt16V(rv.Interface().(map[uint]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintInt16V(v map[uint]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -8961,47 +7587,44 @@ func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64UintptrV(rv2i(rv).(map[uint64]uintptr), e)
+func (f *encFnInfo) fastpathEncMapUintInt32R(rv reflect.Value) {
+	fastpathTV.EncMapUintInt32V(rv.Interface().(map[uint]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64UintptrV(v map[uint64]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintInt32V(v map[uint]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9010,47 +7633,44 @@ func (_ fastpathT) EncMapUint64UintptrV(v map[uint64]uintptr, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				e.encode(v[uint64(k2)])
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64IntV(rv2i(rv).(map[uint64]int), e)
+func (f *encFnInfo) fastpathEncMapUintInt64R(rv reflect.Value) {
+	fastpathTV.EncMapUintInt64V(rv.Interface().(map[uint]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintInt64V(v map[uint]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9059,47 +7679,44 @@ func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int8V(rv2i(rv).(map[uint64]int8), e)
+func (f *encFnInfo) fastpathEncMapUintFloat32R(rv reflect.Value) {
+	fastpathTV.EncMapUintFloat32V(rv.Interface().(map[uint]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintFloat32V(v map[uint]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9108,47 +7725,44 @@ func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[uint(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int16V(rv2i(rv).(map[uint64]int16), e)
+func (f *encFnInfo) fastpathEncMapUintFloat64R(rv reflect.Value) {
+	fastpathTV.EncMapUintFloat64V(rv.Interface().(map[uint]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintFloat64V(v map[uint]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9157,47 +7771,44 @@ func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[uint(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int32V(rv2i(rv).(map[uint64]int32), e)
+func (f *encFnInfo) fastpathEncMapUintBoolR(rv reflect.Value) {
+	fastpathTV.EncMapUintBoolV(rv.Interface().(map[uint]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintBoolV(v map[uint]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9206,47 +7817,44 @@ func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[uint(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int64V(rv2i(rv).(map[uint64]int64), e)
+func (f *encFnInfo) fastpathEncMapUint8IntfR(rv reflect.Value) {
+	fastpathTV.EncMapUint8IntfV(rv.Interface().(map[uint8]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8IntfV(v map[uint8]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9255,47 +7863,44 @@ func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Float32V(rv2i(rv).(map[uint64]float32), e)
+func (f *encFnInfo) fastpathEncMapUint8StringR(rv reflect.Value) {
+	fastpathTV.EncMapUint8StringV(rv.Interface().(map[uint8]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8StringV(v map[uint8]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9304,47 +7909,44 @@ func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeFloat32(v[uint64(k2)])
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[uint8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Float64V(rv2i(rv).(map[uint64]float64), e)
+func (f *encFnInfo) fastpathEncMapUint8UintR(rv reflect.Value) {
+	fastpathTV.EncMapUint8UintV(rv.Interface().(map[uint8]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8UintV(v map[uint8]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9353,47 +7955,44 @@ func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeFloat64(v[uint64(k2)])
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUint64BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64BoolV(rv2i(rv).(map[uint64]bool), e)
+func (f *encFnInfo) fastpathEncMapUint8Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint8V(rv.Interface().(map[uint8]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Uint8V(v map[uint8]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9402,47 +8001,44 @@ func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeBool(v[uint64(k2)])
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrIntfV(rv2i(rv).(map[uintptr]interface{}), e)
+func (f *encFnInfo) fastpathEncMapUint8Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint16V(rv.Interface().(map[uint8]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrIntfV(v map[uintptr]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Uint16V(v map[uint8]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9451,47 +8047,44 @@ func (_ fastpathT) EncMapUintptrIntfV(v map[uintptr]interface{}, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[uintptr(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				e.encode(v[uintptr(k2)])
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrStringV(rv2i(rv).(map[uintptr]string), e)
+func (f *encFnInfo) fastpathEncMapUint8Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint32V(rv.Interface().(map[uint8]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrStringV(v map[uintptr]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Uint32V(v map[uint8]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9500,47 +8093,44 @@ func (_ fastpathT) EncMapUintptrStringV(v map[uintptr]string, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uintptr(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeString(cUTF8, v[uintptr(k2)])
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUintV(rv2i(rv).(map[uintptr]uint), e)
+func (f *encFnInfo) fastpathEncMapUint8Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint64V(rv.Interface().(map[uint8]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrUintV(v map[uintptr]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Uint64V(v map[uint8]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9549,47 +8139,44 @@ func (_ fastpathT) EncMapUintptrUintV(v map[uintptr]uint, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint8V(rv2i(rv).(map[uintptr]uint8), e)
+func (f *encFnInfo) fastpathEncMapUint8UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapUint8UintptrV(rv.Interface().(map[uint8]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrUint8V(v map[uintptr]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8UintptrV(v map[uint8]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9598,47 +8185,44 @@ func (_ fastpathT) EncMapUintptrUint8V(v map[uintptr]uint8, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint16V(rv2i(rv).(map[uintptr]uint16), e)
+func (f *encFnInfo) fastpathEncMapUint8IntR(rv reflect.Value) {
+	fastpathTV.EncMapUint8IntV(rv.Interface().(map[uint8]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrUint16V(v map[uintptr]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8IntV(v map[uint8]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9647,47 +8231,44 @@ func (_ fastpathT) EncMapUintptrUint16V(v map[uintptr]uint16, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint32V(rv2i(rv).(map[uintptr]uint32), e)
+func (f *encFnInfo) fastpathEncMapUint8Int8R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Int8V(rv.Interface().(map[uint8]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrUint32V(v map[uintptr]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Int8V(v map[uint8]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9696,47 +8277,44 @@ func (_ fastpathT) EncMapUintptrUint32V(v map[uintptr]uint32, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint64V(rv2i(rv).(map[uintptr]uint64), e)
+func (f *encFnInfo) fastpathEncMapUint8Int16R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Int16V(rv.Interface().(map[uint8]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrUint64V(v map[uintptr]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Int16V(v map[uint8]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9745,47 +8323,44 @@ func (_ fastpathT) EncMapUintptrUint64V(v map[uintptr]uint64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUintptrV(rv2i(rv).(map[uintptr]uintptr), e)
+func (f *encFnInfo) fastpathEncMapUint8Int32R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Int32V(rv.Interface().(map[uint8]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrUintptrV(v map[uintptr]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Int32V(v map[uint8]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9794,47 +8369,44 @@ func (_ fastpathT) EncMapUintptrUintptrV(v map[uintptr]uintptr, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[uintptr(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				e.encode(v[uintptr(k2)])
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrIntV(rv2i(rv).(map[uintptr]int), e)
+func (f *encFnInfo) fastpathEncMapUint8Int64R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Int64V(rv.Interface().(map[uint8]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrIntV(v map[uintptr]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Int64V(v map[uint8]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9843,47 +8415,44 @@ func (_ fastpathT) EncMapUintptrIntV(v map[uintptr]int, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt8V(rv2i(rv).(map[uintptr]int8), e)
+func (f *encFnInfo) fastpathEncMapUint8Float32R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Float32V(rv.Interface().(map[uint8]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrInt8V(v map[uintptr]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Float32V(v map[uint8]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9892,47 +8461,44 @@ func (_ fastpathT) EncMapUintptrInt8V(v map[uintptr]int8, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[uint8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt16V(rv2i(rv).(map[uintptr]int16), e)
+func (f *encFnInfo) fastpathEncMapUint8Float64R(rv reflect.Value) {
+	fastpathTV.EncMapUint8Float64V(rv.Interface().(map[uint8]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrInt16V(v map[uintptr]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8Float64V(v map[uint8]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9941,47 +8507,44 @@ func (_ fastpathT) EncMapUintptrInt16V(v map[uintptr]int16, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[uint8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt32V(rv2i(rv).(map[uintptr]int32), e)
+func (f *encFnInfo) fastpathEncMapUint8BoolR(rv reflect.Value) {
+	fastpathTV.EncMapUint8BoolV(rv.Interface().(map[uint8]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrInt32V(v map[uintptr]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint8BoolV(v map[uint8]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -9990,47 +8553,44 @@ func (_ fastpathT) EncMapUintptrInt32V(v map[uintptr]int32, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[uint8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt64V(rv2i(rv).(map[uintptr]int64), e)
+func (f *encFnInfo) fastpathEncMapUint16IntfR(rv reflect.Value) {
+	fastpathTV.EncMapUint16IntfV(rv.Interface().(map[uint16]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrInt64V(v map[uintptr]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16IntfV(v map[uint16]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -10039,47 +8599,44 @@ func (_ fastpathT) EncMapUintptrInt64V(v map[uintptr]int64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrFloat32V(rv2i(rv).(map[uintptr]float32), e)
+func (f *encFnInfo) fastpathEncMapUint16StringR(rv reflect.Value) {
+	fastpathTV.EncMapUint16StringV(rv.Interface().(map[uint16]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrFloat32V(v map[uintptr]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16StringV(v map[uint16]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -10088,47 +8645,44 @@ func (_ fastpathT) EncMapUintptrFloat32V(v map[uintptr]float32, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uintptr(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeFloat32(v[uintptr(k2)])
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[uint16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat32(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrFloat64V(rv2i(rv).(map[uintptr]float64), e)
+func (f *encFnInfo) fastpathEncMapUint16UintR(rv reflect.Value) {
+	fastpathTV.EncMapUint16UintV(rv.Interface().(map[uint16]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrFloat64V(v map[uintptr]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16UintV(v map[uint16]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -10137,47 +8691,44 @@ func (_ fastpathT) EncMapUintptrFloat64V(v map[uintptr]float64, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uintptr(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeFloat64(v[uintptr(k2)])
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat64(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapUintptrBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrBoolV(rv2i(rv).(map[uintptr]bool), e)
+func (f *encFnInfo) fastpathEncMapUint16Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint8V(rv.Interface().(map[uint16]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapUintptrBoolV(v map[uintptr]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Uint8V(v map[uint16]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]uint64, len(v))
 		var i int
@@ -10186,2987 +8737,2804 @@ func (_ fastpathT) EncMapUintptrBoolV(v map[uintptr]bool, e *Encoder) {
 			i++
 		}
 		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uintptr(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeBool(v[uintptr(k2)])
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeBool(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntIntfV(rv2i(rv).(map[int]interface{}), e)
+func (f *encFnInfo) fastpathEncMapUint16Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint16V(rv.Interface().(map[uint16]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntIntfV(v map[int]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Uint16V(v map[uint16]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				e.encode(v[int(k2)])
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntStringV(rv2i(rv).(map[int]string), e)
+func (f *encFnInfo) fastpathEncMapUint16Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint32V(rv.Interface().(map[uint16]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntStringV(v map[int]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Uint32V(v map[uint16]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeString(cUTF8, v[int(k2)])
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUintV(rv2i(rv).(map[int]uint), e)
+func (f *encFnInfo) fastpathEncMapUint16Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint64V(rv.Interface().(map[uint16]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntUintV(v map[int]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Uint64V(v map[uint16]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint8V(rv2i(rv).(map[int]uint8), e)
+func (f *encFnInfo) fastpathEncMapUint16UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapUint16UintptrV(rv.Interface().(map[uint16]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntUint8V(v map[int]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16UintptrV(v map[uint16]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint16V(rv2i(rv).(map[int]uint16), e)
+func (f *encFnInfo) fastpathEncMapUint16IntR(rv reflect.Value) {
+	fastpathTV.EncMapUint16IntV(rv.Interface().(map[uint16]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntUint16V(v map[int]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16IntV(v map[uint16]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint32V(rv2i(rv).(map[int]uint32), e)
+func (f *encFnInfo) fastpathEncMapUint16Int8R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Int8V(rv.Interface().(map[uint16]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntUint32V(v map[int]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Int8V(v map[uint16]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint64V(rv2i(rv).(map[int]uint64), e)
+func (f *encFnInfo) fastpathEncMapUint16Int16R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Int16V(rv.Interface().(map[uint16]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntUint64V(v map[int]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Int16V(v map[uint16]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUintptrV(rv2i(rv).(map[int]uintptr), e)
+func (f *encFnInfo) fastpathEncMapUint16Int32R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Int32V(rv.Interface().(map[uint16]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntUintptrV(v map[int]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Int32V(v map[uint16]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				e.encode(v[int(k2)])
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntIntV(rv2i(rv).(map[int]int), e)
+func (f *encFnInfo) fastpathEncMapUint16Int64R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Int64V(rv.Interface().(map[uint16]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntIntV(v map[int]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Int64V(v map[uint16]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt8V(rv2i(rv).(map[int]int8), e)
+func (f *encFnInfo) fastpathEncMapUint16Float32R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Float32V(rv.Interface().(map[uint16]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntInt8V(v map[int]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Float32V(v map[uint16]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[uint16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt16V(rv2i(rv).(map[int]int16), e)
+func (f *encFnInfo) fastpathEncMapUint16Float64R(rv reflect.Value) {
+	fastpathTV.EncMapUint16Float64V(rv.Interface().(map[uint16]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntInt16V(v map[int]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16Float64V(v map[uint16]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[uint16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt32V(rv2i(rv).(map[int]int32), e)
+func (f *encFnInfo) fastpathEncMapUint16BoolR(rv reflect.Value) {
+	fastpathTV.EncMapUint16BoolV(rv.Interface().(map[uint16]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntInt32V(v map[int]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint16BoolV(v map[uint16]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[uint16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt64V(rv2i(rv).(map[int]int64), e)
+func (f *encFnInfo) fastpathEncMapUint32IntfR(rv reflect.Value) {
+	fastpathTV.EncMapUint32IntfV(rv.Interface().(map[uint32]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntInt64V(v map[int]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32IntfV(v map[uint32]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntFloat32V(rv2i(rv).(map[int]float32), e)
+func (f *encFnInfo) fastpathEncMapUint32StringR(rv reflect.Value) {
+	fastpathTV.EncMapUint32StringV(rv.Interface().(map[uint32]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntFloat32V(v map[int]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32StringV(v map[uint32]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeFloat32(v[int(k2)])
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[uint32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntFloat64V(rv2i(rv).(map[int]float64), e)
+func (f *encFnInfo) fastpathEncMapUint32UintR(rv reflect.Value) {
+	fastpathTV.EncMapUint32UintV(rv.Interface().(map[uint32]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntFloat64V(v map[int]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32UintV(v map[uint32]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeFloat64(v[int(k2)])
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapIntBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntBoolV(rv2i(rv).(map[int]bool), e)
+func (f *encFnInfo) fastpathEncMapUint32Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint8V(rv.Interface().(map[uint32]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapIntBoolV(v map[int]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Uint8V(v map[uint32]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeBool(v[int(k2)])
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8IntfV(rv2i(rv).(map[int8]interface{}), e)
+func (f *encFnInfo) fastpathEncMapUint32Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint16V(rv.Interface().(map[uint32]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8IntfV(v map[int8]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Uint16V(v map[uint32]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int8(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				e.encode(v[int8(k2)])
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8StringV(rv2i(rv).(map[int8]string), e)
+func (f *encFnInfo) fastpathEncMapUint32Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint32V(rv.Interface().(map[uint32]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8StringV(v map[int8]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Uint32V(v map[uint32]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int8(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeString(cUTF8, v[int8(k2)])
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8UintV(rv2i(rv).(map[int8]uint), e)
+func (f *encFnInfo) fastpathEncMapUint32Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint64V(rv.Interface().(map[uint32]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8UintV(v map[int8]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Uint64V(v map[uint32]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint8V(rv2i(rv).(map[int8]uint8), e)
+func (f *encFnInfo) fastpathEncMapUint32UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapUint32UintptrV(rv.Interface().(map[uint32]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Uint8V(v map[int8]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32UintptrV(v map[uint32]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint16V(rv2i(rv).(map[int8]uint16), e)
+func (f *encFnInfo) fastpathEncMapUint32IntR(rv reflect.Value) {
+	fastpathTV.EncMapUint32IntV(rv.Interface().(map[uint32]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Uint16V(v map[int8]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32IntV(v map[uint32]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint32V(rv2i(rv).(map[int8]uint32), e)
+func (f *encFnInfo) fastpathEncMapUint32Int8R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Int8V(rv.Interface().(map[uint32]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Uint32V(v map[int8]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Int8V(v map[uint32]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint64V(rv2i(rv).(map[int8]uint64), e)
+func (f *encFnInfo) fastpathEncMapUint32Int16R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Int16V(rv.Interface().(map[uint32]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Uint64V(v map[int8]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Int16V(v map[uint32]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8UintptrV(rv2i(rv).(map[int8]uintptr), e)
+func (f *encFnInfo) fastpathEncMapUint32Int32R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Int32V(rv.Interface().(map[uint32]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8UintptrV(v map[int8]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Int32V(v map[uint32]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int8(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				e.encode(v[int8(k2)])
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8IntV(rv2i(rv).(map[int8]int), e)
+func (f *encFnInfo) fastpathEncMapUint32Int64R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Int64V(rv.Interface().(map[uint32]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8IntV(v map[int8]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint32(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int8V(rv2i(rv).(map[int8]int8), e)
+func (f *encFnInfo) fastpathEncMapUint32Float32R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Float32V(rv.Interface().(map[uint32]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Int8V(v map[int8]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[uint32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int16V(rv2i(rv).(map[int8]int16), e)
+func (f *encFnInfo) fastpathEncMapUint32Float64R(rv reflect.Value) {
+	fastpathTV.EncMapUint32Float64V(rv.Interface().(map[uint32]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Int16V(v map[int8]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[uint32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int32V(rv2i(rv).(map[int8]int32), e)
+func (f *encFnInfo) fastpathEncMapUint32BoolR(rv reflect.Value) {
+	fastpathTV.EncMapUint32BoolV(rv.Interface().(map[uint32]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Int32V(v map[int8]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[uint32(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int64V(rv2i(rv).(map[int8]int64), e)
+func (f *encFnInfo) fastpathEncMapUint64IntfR(rv reflect.Value) {
+	fastpathTV.EncMapUint64IntfV(rv.Interface().(map[uint64]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Int64V(v map[int8]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Float32V(rv2i(rv).(map[int8]float32), e)
+func (f *encFnInfo) fastpathEncMapUint64StringR(rv reflect.Value) {
+	fastpathTV.EncMapUint64StringV(rv.Interface().(map[uint64]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Float32V(v map[int8]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int8(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeFloat32(v[int8(k2)])
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[uint64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Float64V(rv2i(rv).(map[int8]float64), e)
+func (f *encFnInfo) fastpathEncMapUint64UintR(rv reflect.Value) {
+	fastpathTV.EncMapUint64UintV(rv.Interface().(map[uint64]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8Float64V(v map[int8]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int8(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeFloat64(v[int8(k2)])
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt8BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8BoolV(rv2i(rv).(map[int8]bool), e)
+func (f *encFnInfo) fastpathEncMapUint64Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint8V(rv.Interface().(map[uint64]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt8BoolV(v map[int8]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int8(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeBool(v[int8(k2)])
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16IntfV(rv2i(rv).(map[int16]interface{}), e)
+func (f *encFnInfo) fastpathEncMapUint64Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint16V(rv.Interface().(map[uint64]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16IntfV(v map[int16]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int16(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				e.encode(v[int16(k2)])
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16StringV(rv2i(rv).(map[int16]string), e)
+func (f *encFnInfo) fastpathEncMapUint64Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint32V(rv.Interface().(map[uint64]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16StringV(v map[int16]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int16(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeString(cUTF8, v[int16(k2)])
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16UintV(rv2i(rv).(map[int16]uint), e)
+func (f *encFnInfo) fastpathEncMapUint64Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint64V(rv.Interface().(map[uint64]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16UintV(v map[int16]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint8V(rv2i(rv).(map[int16]uint8), e)
+func (f *encFnInfo) fastpathEncMapUint64UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapUint64UintptrV(rv.Interface().(map[uint64]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Uint8V(v map[int16]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64UintptrV(v map[uint64]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uint64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint16V(rv2i(rv).(map[int16]uint16), e)
+func (f *encFnInfo) fastpathEncMapUint64IntR(rv reflect.Value) {
+	fastpathTV.EncMapUint64IntV(rv.Interface().(map[uint64]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Uint16V(v map[int16]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint32V(rv2i(rv).(map[int16]uint32), e)
+func (f *encFnInfo) fastpathEncMapUint64Int8R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Int8V(rv.Interface().(map[uint64]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Uint32V(v map[int16]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint64V(rv2i(rv).(map[int16]uint64), e)
+func (f *encFnInfo) fastpathEncMapUint64Int16R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Int16V(rv.Interface().(map[uint64]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Uint64V(v map[int16]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16UintptrV(rv2i(rv).(map[int16]uintptr), e)
+func (f *encFnInfo) fastpathEncMapUint64Int32R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Int32V(rv.Interface().(map[uint64]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16UintptrV(v map[int16]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int16(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				e.encode(v[int16(k2)])
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16IntV(rv2i(rv).(map[int16]int), e)
+func (f *encFnInfo) fastpathEncMapUint64Int64R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Int64V(rv.Interface().(map[uint64]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16IntV(v map[int16]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uint64(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int8V(rv2i(rv).(map[int16]int8), e)
+func (f *encFnInfo) fastpathEncMapUint64Float32R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Float32V(rv.Interface().(map[uint64]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Int8V(v map[int16]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[uint64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int16V(rv2i(rv).(map[int16]int16), e)
+func (f *encFnInfo) fastpathEncMapUint64Float64R(rv reflect.Value) {
+	fastpathTV.EncMapUint64Float64V(rv.Interface().(map[uint64]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Int16V(v map[int16]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[uint64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int32V(rv2i(rv).(map[int16]int32), e)
+func (f *encFnInfo) fastpathEncMapUint64BoolR(rv reflect.Value) {
+	fastpathTV.EncMapUint64BoolV(rv.Interface().(map[uint64]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Int32V(v map[int16]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
+			ee.EncodeUint(uint64(uint64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[uint64(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeUint(uint64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int64V(rv2i(rv).(map[int16]int64), e)
+func (f *encFnInfo) fastpathEncMapUintptrIntfR(rv reflect.Value) {
+	fastpathTV.EncMapUintptrIntfV(rv.Interface().(map[uintptr]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Int64V(v map[int16]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrIntfV(v map[uintptr]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uintptr(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Float32V(rv2i(rv).(map[int16]float32), e)
+func (f *encFnInfo) fastpathEncMapUintptrStringR(rv reflect.Value) {
+	fastpathTV.EncMapUintptrStringV(rv.Interface().(map[uintptr]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Float32V(v map[int16]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrStringV(v map[uintptr]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int16(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeFloat32(v[int16(k2)])
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[uintptr(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Float64V(rv2i(rv).(map[int16]float64), e)
+func (f *encFnInfo) fastpathEncMapUintptrUintR(rv reflect.Value) {
+	fastpathTV.EncMapUintptrUintV(rv.Interface().(map[uintptr]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16Float64V(v map[int16]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrUintV(v map[uintptr]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int16(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeFloat64(v[int16(k2)])
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt16BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16BoolV(rv2i(rv).(map[int16]bool), e)
+func (f *encFnInfo) fastpathEncMapUintptrUint8R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint8V(rv.Interface().(map[uintptr]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt16BoolV(v map[int16]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrUint8V(v map[uintptr]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int16(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeBool(v[int16(k2)])
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32IntfV(rv2i(rv).(map[int32]interface{}), e)
+func (f *encFnInfo) fastpathEncMapUintptrUint16R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint16V(rv.Interface().(map[uintptr]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32IntfV(v map[int32]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrUint16V(v map[uintptr]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int32(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				e.encode(v[int32(k2)])
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32StringV(rv2i(rv).(map[int32]string), e)
+func (f *encFnInfo) fastpathEncMapUintptrUint32R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint32V(rv.Interface().(map[uintptr]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32StringV(v map[int32]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrUint32V(v map[uintptr]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int32(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeString(cUTF8, v[int32(k2)])
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32UintV(rv2i(rv).(map[int32]uint), e)
+func (f *encFnInfo) fastpathEncMapUintptrUint64R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint64V(rv.Interface().(map[uintptr]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32UintV(v map[int32]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrUint64V(v map[uintptr]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint8V(rv2i(rv).(map[int32]uint8), e)
+func (f *encFnInfo) fastpathEncMapUintptrUintptrR(rv reflect.Value) {
+	fastpathTV.EncMapUintptrUintptrV(rv.Interface().(map[uintptr]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Uint8V(v map[int32]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrUintptrV(v map[uintptr]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[uintptr(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint16V(rv2i(rv).(map[int32]uint16), e)
+func (f *encFnInfo) fastpathEncMapUintptrIntR(rv reflect.Value) {
+	fastpathTV.EncMapUintptrIntV(rv.Interface().(map[uintptr]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Uint16V(v map[int32]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrIntV(v map[uintptr]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint32V(rv2i(rv).(map[int32]uint32), e)
+func (f *encFnInfo) fastpathEncMapUintptrInt8R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt8V(rv.Interface().(map[uintptr]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Uint32V(v map[int32]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrInt8V(v map[uintptr]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint64V(rv2i(rv).(map[int32]uint64), e)
+func (f *encFnInfo) fastpathEncMapUintptrInt16R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt16V(rv.Interface().(map[uintptr]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Uint64V(v map[int32]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrInt16V(v map[uintptr]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32UintptrV(rv2i(rv).(map[int32]uintptr), e)
+func (f *encFnInfo) fastpathEncMapUintptrInt32R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt32V(rv.Interface().(map[uintptr]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32UintptrV(v map[int32]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrInt32V(v map[uintptr]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int32(k2)])
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				e.encode(v[int32(k2)])
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32IntV(rv2i(rv).(map[int32]int), e)
+func (f *encFnInfo) fastpathEncMapUintptrInt64R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt64V(rv.Interface().(map[uintptr]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32IntV(v map[int32]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrInt64V(v map[uintptr]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[uintptr(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int8V(rv2i(rv).(map[int32]int8), e)
+func (f *encFnInfo) fastpathEncMapUintptrFloat32R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrFloat32V(rv.Interface().(map[uintptr]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Int8V(v map[int32]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrFloat32V(v map[uintptr]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[uintptr(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int16V(rv2i(rv).(map[int32]int16), e)
+func (f *encFnInfo) fastpathEncMapUintptrFloat64R(rv reflect.Value) {
+	fastpathTV.EncMapUintptrFloat64V(rv.Interface().(map[uintptr]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Int16V(v map[int32]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrFloat64V(v map[uintptr]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[uintptr(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int32V(rv2i(rv).(map[int32]int32), e)
+func (f *encFnInfo) fastpathEncMapUintptrBoolR(rv reflect.Value) {
+	fastpathTV.EncMapUintptrBoolV(rv.Interface().(map[uintptr]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Int32V(v map[int32]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapUintptrBoolV(v map[uintptr]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]int64, len(v))
+		v2 := make([]uint64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = int64(k)
+			v2[i] = uint64(k)
 			i++
 		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
+		sort.Sort(uintSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
+			e.encode(uintptr(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[uintptr(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			e.encode(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int64V(rv2i(rv).(map[int32]int64), e)
+func (f *encFnInfo) fastpathEncMapIntIntfR(rv reflect.Value) {
+	fastpathTV.EncMapIntIntfV(rv.Interface().(map[int]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntIntfV(v map[int]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13175,47 +11543,44 @@ func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[int(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Float32V(rv2i(rv).(map[int32]float32), e)
+func (f *encFnInfo) fastpathEncMapIntStringR(rv reflect.Value) {
+	fastpathTV.EncMapIntStringV(rv.Interface().(map[int]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntStringV(v map[int]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13224,47 +11589,44 @@ func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int32(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeFloat32(v[int32(k2)])
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[int(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Float64V(rv2i(rv).(map[int32]float64), e)
+func (f *encFnInfo) fastpathEncMapIntUintR(rv reflect.Value) {
+	fastpathTV.EncMapIntUintV(rv.Interface().(map[int]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntUintV(v map[int]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13273,47 +11635,44 @@ func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int32(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeFloat64(v[int32(k2)])
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt32BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32BoolV(rv2i(rv).(map[int32]bool), e)
+func (f *encFnInfo) fastpathEncMapIntUint8R(rv reflect.Value) {
+	fastpathTV.EncMapIntUint8V(rv.Interface().(map[int]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntUint8V(v map[int]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13322,47 +11681,44 @@ func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int32(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeBool(v[int32(k2)])
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64IntfV(rv2i(rv).(map[int64]interface{}), e)
+func (f *encFnInfo) fastpathEncMapIntUint16R(rv reflect.Value) {
+	fastpathTV.EncMapIntUint16V(rv.Interface().(map[int]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntUint16V(v map[int]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13371,47 +11727,44 @@ func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				e.encode(v[int64(k2)])
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64StringV(rv2i(rv).(map[int64]string), e)
+func (f *encFnInfo) fastpathEncMapIntUint32R(rv reflect.Value) {
+	fastpathTV.EncMapIntUint32V(rv.Interface().(map[int]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64StringV(v map[int64]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntUint32V(v map[int]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13420,47 +11773,44 @@ func (_ fastpathT) EncMapInt64StringV(v map[int64]string, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeString(cUTF8, v[int64(k2)])
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64UintV(rv2i(rv).(map[int64]uint), e)
+func (f *encFnInfo) fastpathEncMapIntUint64R(rv reflect.Value) {
+	fastpathTV.EncMapIntUint64V(rv.Interface().(map[int]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntUint64V(v map[int]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13469,47 +11819,44 @@ func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint8V(rv2i(rv).(map[int64]uint8), e)
+func (f *encFnInfo) fastpathEncMapIntUintptrR(rv reflect.Value) {
+	fastpathTV.EncMapIntUintptrV(rv.Interface().(map[int]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntUintptrV(v map[int]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13518,47 +11865,44 @@ func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[int(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint16V(rv2i(rv).(map[int64]uint16), e)
+func (f *encFnInfo) fastpathEncMapIntIntR(rv reflect.Value) {
+	fastpathTV.EncMapIntIntV(rv.Interface().(map[int]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntIntV(v map[int]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13567,47 +11911,44 @@ func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint32V(rv2i(rv).(map[int64]uint32), e)
+func (f *encFnInfo) fastpathEncMapIntInt8R(rv reflect.Value) {
+	fastpathTV.EncMapIntInt8V(rv.Interface().(map[int]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntInt8V(v map[int]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13616,47 +11957,44 @@ func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint64V(rv2i(rv).(map[int64]uint64), e)
+func (f *encFnInfo) fastpathEncMapIntInt16R(rv reflect.Value) {
+	fastpathTV.EncMapIntInt16V(rv.Interface().(map[int]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntInt16V(v map[int]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13665,47 +12003,44 @@ func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64UintptrV(rv2i(rv).(map[int64]uintptr), e)
+func (f *encFnInfo) fastpathEncMapIntInt32R(rv reflect.Value) {
+	fastpathTV.EncMapIntInt32V(rv.Interface().(map[int]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64UintptrV(v map[int64]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntInt32V(v map[int]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13714,47 +12049,44 @@ func (_ fastpathT) EncMapInt64UintptrV(v map[int64]uintptr, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				e.encode(v[int64(k2)])
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64IntV(rv2i(rv).(map[int64]int), e)
+func (f *encFnInfo) fastpathEncMapIntInt64R(rv reflect.Value) {
+	fastpathTV.EncMapIntInt64V(rv.Interface().(map[int]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64IntV(v map[int64]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntInt64V(v map[int]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13763,47 +12095,44 @@ func (_ fastpathT) EncMapInt64IntV(v map[int64]int, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int8V(rv2i(rv).(map[int64]int8), e)
+func (f *encFnInfo) fastpathEncMapIntFloat32R(rv reflect.Value) {
+	fastpathTV.EncMapIntFloat32V(rv.Interface().(map[int]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntFloat32V(v map[int]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13812,47 +12141,44 @@ func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[int(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int16V(rv2i(rv).(map[int64]int16), e)
+func (f *encFnInfo) fastpathEncMapIntFloat64R(rv reflect.Value) {
+	fastpathTV.EncMapIntFloat64V(rv.Interface().(map[int]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntFloat64V(v map[int]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13861,47 +12187,44 @@ func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[int(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int32V(rv2i(rv).(map[int64]int32), e)
+func (f *encFnInfo) fastpathEncMapIntBoolR(rv reflect.Value) {
+	fastpathTV.EncMapIntBoolV(rv.Interface().(map[int]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapIntBoolV(v map[int]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13910,47 +12233,44 @@ func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
+			ee.EncodeInt(int64(int(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[int(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int64V(rv2i(rv).(map[int64]int64), e)
+func (f *encFnInfo) fastpathEncMapInt8IntfR(rv reflect.Value) {
+	fastpathTV.EncMapInt8IntfV(rv.Interface().(map[int8]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8IntfV(v map[int8]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -13959,47 +12279,44 @@ func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[int8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Float32V(rv2i(rv).(map[int64]float32), e)
+func (f *encFnInfo) fastpathEncMapInt8StringR(rv reflect.Value) {
+	fastpathTV.EncMapInt8StringV(rv.Interface().(map[int8]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8StringV(v map[int8]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -14008,47 +12325,44 @@ func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeFloat32(v[int64(k2)])
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[int8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Float64V(rv2i(rv).(map[int64]float64), e)
+func (f *encFnInfo) fastpathEncMapInt8UintR(rv reflect.Value) {
+	fastpathTV.EncMapInt8UintV(rv.Interface().(map[int8]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8UintV(v map[int8]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -14057,47 +12371,44 @@ func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeFloat64(v[int64(k2)])
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapInt64BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64BoolV(rv2i(rv).(map[int64]bool), e)
+func (f *encFnInfo) fastpathEncMapInt8Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint8V(rv.Interface().(map[int8]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Uint8V(v map[int8]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
 		v2 := make([]int64, len(v))
 		var i int
@@ -14106,3614 +12417,5705 @@ func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, e *Encoder) {
 			i++
 		}
 		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int64(k2)])
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeBool(v[int64(k2)])
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolIntfV(rv2i(rv).(map[bool]interface{}), e)
+func (f *encFnInfo) fastpathEncMapInt8Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint16V(rv.Interface().(map[int8]uint16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolIntfV(v map[bool]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Uint16V(v map[int8]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[bool(k2)])
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				e.encode(v[bool(k2)])
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				e.encode(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolStringV(rv2i(rv).(map[bool]string), e)
+func (f *encFnInfo) fastpathEncMapInt8Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint32V(rv.Interface().(map[int8]uint32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolStringV(v map[bool]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Uint32V(v map[int8]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[bool(k2)])
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeString(cUTF8, v[bool(k2)])
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeString(cUTF8, v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUintV(rv2i(rv).(map[bool]uint), e)
+func (f *encFnInfo) fastpathEncMapInt8Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint64V(rv.Interface().(map[int8]uint64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolUintV(v map[bool]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Uint64V(v map[int8]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint8V(rv2i(rv).(map[bool]uint8), e)
+func (f *encFnInfo) fastpathEncMapInt8UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapInt8UintptrV(rv.Interface().(map[int8]uintptr), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolUint8V(v map[bool]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8UintptrV(v map[int8]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[int8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint16V(rv2i(rv).(map[bool]uint16), e)
+func (f *encFnInfo) fastpathEncMapInt8IntR(rv reflect.Value) {
+	fastpathTV.EncMapInt8IntV(rv.Interface().(map[int8]int), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolUint16V(v map[bool]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8IntV(v map[int8]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint32V(rv2i(rv).(map[bool]uint32), e)
+func (f *encFnInfo) fastpathEncMapInt8Int8R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Int8V(rv.Interface().(map[int8]int8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolUint32V(v map[bool]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Int8V(v map[int8]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint64V(rv2i(rv).(map[bool]uint64), e)
+func (f *encFnInfo) fastpathEncMapInt8Int16R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Int16V(rv.Interface().(map[int8]int16), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolUint64V(v map[bool]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Int16V(v map[int8]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUintptrV(rv2i(rv).(map[bool]uintptr), e)
+func (f *encFnInfo) fastpathEncMapInt8Int32R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Int32V(rv.Interface().(map[int8]int32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolUintptrV(v map[bool]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Int32V(v map[int8]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[bool(k2)])
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				e.encode(v[bool(k2)])
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				e.encode(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolIntV(rv2i(rv).(map[bool]int), e)
+func (f *encFnInfo) fastpathEncMapInt8Int64R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Int64V(rv.Interface().(map[int8]int64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolIntV(v map[bool]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Int64V(v map[int8]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v[int8(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeInt(int64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt8V(rv2i(rv).(map[bool]int8), e)
+func (f *encFnInfo) fastpathEncMapInt8Float32R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Float32V(rv.Interface().(map[int8]float32), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolInt8V(v map[bool]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Float32V(v map[int8]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v[int8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat32(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt16V(rv2i(rv).(map[bool]int16), e)
+func (f *encFnInfo) fastpathEncMapInt8Float64R(rv reflect.Value) {
+	fastpathTV.EncMapInt8Float64V(rv.Interface().(map[int8]float64), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolInt16V(v map[bool]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8Float64V(v map[int8]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v[int8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeFloat64(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt32V(rv2i(rv).(map[bool]int32), e)
+func (f *encFnInfo) fastpathEncMapInt8BoolR(rv reflect.Value) {
+	fastpathTV.EncMapInt8BoolV(rv.Interface().(map[int8]bool), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolInt32V(v map[bool]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt8BoolV(v map[int8]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
+			ee.EncodeInt(int64(int8(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v[int8(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeBool(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt64V(rv2i(rv).(map[bool]int64), e)
+func (f *encFnInfo) fastpathEncMapInt16IntfR(rv reflect.Value) {
+	fastpathTV.EncMapInt16IntfV(rv.Interface().(map[int16]interface{}), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolInt64V(v map[bool]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt16IntfV(v map[int16]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v[int16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			e.encode(v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolFloat32V(rv2i(rv).(map[bool]float32), e)
+func (f *encFnInfo) fastpathEncMapInt16StringR(rv reflect.Value) {
+	fastpathTV.EncMapInt16StringV(rv.Interface().(map[int16]string), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolFloat32V(v map[bool]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt16StringV(v map[int16]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[bool(k2)])
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeFloat32(v[bool(k2)])
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v[int16(k2)])
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeFloat32(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeString(c_UTF8, v2)
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolFloat64V(rv2i(rv).(map[bool]float64), e)
+func (f *encFnInfo) fastpathEncMapInt16UintR(rv reflect.Value) {
+	fastpathTV.EncMapInt16UintV(rv.Interface().(map[int16]uint), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolFloat64V(v map[bool]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt16UintV(v map[int16]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[bool(k2)])
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeFloat64(v[bool(k2)])
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeFloat64(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-func (e *Encoder) fastpathEncMapBoolBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolBoolV(rv2i(rv).(map[bool]bool), e)
+func (f *encFnInfo) fastpathEncMapInt16Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint8V(rv.Interface().(map[int16]uint8), fastpathCheckNilFalse, f.e)
 }
-func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
+func (_ fastpathT) EncMapInt16Uint8V(v map[int16]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
 		return
 	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
+	ee.EncodeMapStart(len(v))
 	if e.h.Canonical {
-		v2 := make([]bool, len(v))
+		v2 := make([]int64, len(v))
 		var i int
 		for k, _ := range v {
-			v2[i] = bool(k)
+			v2[i] = int64(k)
 			i++
 		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[bool(k2)])
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeBool(v[bool(k2)])
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v[int16(k2)]))
 		}
 	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
 			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeBool(v2)
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
 			}
+			ee.EncodeUint(uint64(v2))
 		}
 	}
-	ee.WriteMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 }
 
-// -- decode
-
-// -- -- fast path type switch
-func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
-	var changed bool
-	switch v := iv.(type) {
-
-	case []interface{}:
-		var v2 []interface{}
-		v2, changed = fastpathTV.DecSliceIntfV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]interface{}:
-		var v2 []interface{}
-		v2, changed = fastpathTV.DecSliceIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []string:
-		var v2 []string
-		v2, changed = fastpathTV.DecSliceStringV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]string:
-		var v2 []string
-		v2, changed = fastpathTV.DecSliceStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []float32:
-		var v2 []float32
-		v2, changed = fastpathTV.DecSliceFloat32V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]float32:
-		var v2 []float32
-		v2, changed = fastpathTV.DecSliceFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []float64:
-		var v2 []float64
-		v2, changed = fastpathTV.DecSliceFloat64V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]float64:
-		var v2 []float64
-		v2, changed = fastpathTV.DecSliceFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint:
-		var v2 []uint
-		v2, changed = fastpathTV.DecSliceUintV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint:
-		var v2 []uint
-		v2, changed = fastpathTV.DecSliceUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint16:
-		var v2 []uint16
-		v2, changed = fastpathTV.DecSliceUint16V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint16:
-		var v2 []uint16
-		v2, changed = fastpathTV.DecSliceUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint32:
-		var v2 []uint32
-		v2, changed = fastpathTV.DecSliceUint32V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint32:
-		var v2 []uint32
-		v2, changed = fastpathTV.DecSliceUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint64:
-		var v2 []uint64
-		v2, changed = fastpathTV.DecSliceUint64V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint64:
-		var v2 []uint64
-		v2, changed = fastpathTV.DecSliceUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uintptr:
-		var v2 []uintptr
-		v2, changed = fastpathTV.DecSliceUintptrV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uintptr:
-		var v2 []uintptr
-		v2, changed = fastpathTV.DecSliceUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int:
-		var v2 []int
-		v2, changed = fastpathTV.DecSliceIntV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int:
-		var v2 []int
-		v2, changed = fastpathTV.DecSliceIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int8:
-		var v2 []int8
-		v2, changed = fastpathTV.DecSliceInt8V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int8:
-		var v2 []int8
-		v2, changed = fastpathTV.DecSliceInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int16:
-		var v2 []int16
-		v2, changed = fastpathTV.DecSliceInt16V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int16:
-		var v2 []int16
-		v2, changed = fastpathTV.DecSliceInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int32:
-		var v2 []int32
-		v2, changed = fastpathTV.DecSliceInt32V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int32:
-		var v2 []int32
-		v2, changed = fastpathTV.DecSliceInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int64:
-		var v2 []int64
-		v2, changed = fastpathTV.DecSliceInt64V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int64:
-		var v2 []int64
-		v2, changed = fastpathTV.DecSliceInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []bool:
-		var v2 []bool
-		v2, changed = fastpathTV.DecSliceBoolV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]bool:
-		var v2 []bool
-		v2, changed = fastpathTV.DecSliceBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-
-	case map[interface{}]interface{}:
-		fastpathTV.DecMapIntfIntfV(v, false, d)
-	case *map[interface{}]interface{}:
-		var v2 map[interface{}]interface{}
-		v2, changed = fastpathTV.DecMapIntfIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]string:
-		fastpathTV.DecMapIntfStringV(v, false, d)
-	case *map[interface{}]string:
-		var v2 map[interface{}]string
-		v2, changed = fastpathTV.DecMapIntfStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint:
-		fastpathTV.DecMapIntfUintV(v, false, d)
-	case *map[interface{}]uint:
-		var v2 map[interface{}]uint
-		v2, changed = fastpathTV.DecMapIntfUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint8:
-		fastpathTV.DecMapIntfUint8V(v, false, d)
-	case *map[interface{}]uint8:
-		var v2 map[interface{}]uint8
-		v2, changed = fastpathTV.DecMapIntfUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint16:
-		fastpathTV.DecMapIntfUint16V(v, false, d)
-	case *map[interface{}]uint16:
-		var v2 map[interface{}]uint16
-		v2, changed = fastpathTV.DecMapIntfUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint32:
-		fastpathTV.DecMapIntfUint32V(v, false, d)
-	case *map[interface{}]uint32:
-		var v2 map[interface{}]uint32
-		v2, changed = fastpathTV.DecMapIntfUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint64:
-		fastpathTV.DecMapIntfUint64V(v, false, d)
-	case *map[interface{}]uint64:
-		var v2 map[interface{}]uint64
-		v2, changed = fastpathTV.DecMapIntfUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uintptr:
-		fastpathTV.DecMapIntfUintptrV(v, false, d)
-	case *map[interface{}]uintptr:
-		var v2 map[interface{}]uintptr
-		v2, changed = fastpathTV.DecMapIntfUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int:
-		fastpathTV.DecMapIntfIntV(v, false, d)
-	case *map[interface{}]int:
-		var v2 map[interface{}]int
-		v2, changed = fastpathTV.DecMapIntfIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int8:
-		fastpathTV.DecMapIntfInt8V(v, false, d)
-	case *map[interface{}]int8:
-		var v2 map[interface{}]int8
-		v2, changed = fastpathTV.DecMapIntfInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int16:
-		fastpathTV.DecMapIntfInt16V(v, false, d)
-	case *map[interface{}]int16:
-		var v2 map[interface{}]int16
-		v2, changed = fastpathTV.DecMapIntfInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int32:
-		fastpathTV.DecMapIntfInt32V(v, false, d)
-	case *map[interface{}]int32:
-		var v2 map[interface{}]int32
-		v2, changed = fastpathTV.DecMapIntfInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int64:
-		fastpathTV.DecMapIntfInt64V(v, false, d)
-	case *map[interface{}]int64:
-		var v2 map[interface{}]int64
-		v2, changed = fastpathTV.DecMapIntfInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]float32:
-		fastpathTV.DecMapIntfFloat32V(v, false, d)
-	case *map[interface{}]float32:
-		var v2 map[interface{}]float32
-		v2, changed = fastpathTV.DecMapIntfFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]float64:
-		fastpathTV.DecMapIntfFloat64V(v, false, d)
-	case *map[interface{}]float64:
-		var v2 map[interface{}]float64
-		v2, changed = fastpathTV.DecMapIntfFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]bool:
-		fastpathTV.DecMapIntfBoolV(v, false, d)
-	case *map[interface{}]bool:
-		var v2 map[interface{}]bool
-		v2, changed = fastpathTV.DecMapIntfBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]interface{}:
-		fastpathTV.DecMapStringIntfV(v, false, d)
-	case *map[string]interface{}:
-		var v2 map[string]interface{}
-		v2, changed = fastpathTV.DecMapStringIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]string:
-		fastpathTV.DecMapStringStringV(v, false, d)
-	case *map[string]string:
-		var v2 map[string]string
-		v2, changed = fastpathTV.DecMapStringStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint:
-		fastpathTV.DecMapStringUintV(v, false, d)
-	case *map[string]uint:
-		var v2 map[string]uint
-		v2, changed = fastpathTV.DecMapStringUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint8:
-		fastpathTV.DecMapStringUint8V(v, false, d)
-	case *map[string]uint8:
-		var v2 map[string]uint8
-		v2, changed = fastpathTV.DecMapStringUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint16:
-		fastpathTV.DecMapStringUint16V(v, false, d)
-	case *map[string]uint16:
-		var v2 map[string]uint16
-		v2, changed = fastpathTV.DecMapStringUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint32:
-		fastpathTV.DecMapStringUint32V(v, false, d)
-	case *map[string]uint32:
-		var v2 map[string]uint32
-		v2, changed = fastpathTV.DecMapStringUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint64:
-		fastpathTV.DecMapStringUint64V(v, false, d)
-	case *map[string]uint64:
-		var v2 map[string]uint64
-		v2, changed = fastpathTV.DecMapStringUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uintptr:
-		fastpathTV.DecMapStringUintptrV(v, false, d)
-	case *map[string]uintptr:
-		var v2 map[string]uintptr
-		v2, changed = fastpathTV.DecMapStringUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int:
-		fastpathTV.DecMapStringIntV(v, false, d)
-	case *map[string]int:
-		var v2 map[string]int
-		v2, changed = fastpathTV.DecMapStringIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int8:
-		fastpathTV.DecMapStringInt8V(v, false, d)
-	case *map[string]int8:
-		var v2 map[string]int8
-		v2, changed = fastpathTV.DecMapStringInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int16:
-		fastpathTV.DecMapStringInt16V(v, false, d)
-	case *map[string]int16:
-		var v2 map[string]int16
-		v2, changed = fastpathTV.DecMapStringInt16V(*v, true, d)
-		if changed {
-			*v = v2
+func (f *encFnInfo) fastpathEncMapInt16Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint16V(rv.Interface().(map[int16]uint16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Uint16V(v map[int16]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[string]int32:
-		fastpathTV.DecMapStringInt32V(v, false, d)
-	case *map[string]int32:
-		var v2 map[string]int32
-		v2, changed = fastpathTV.DecMapStringInt32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int16(k2)]))
 		}
-	case map[string]int64:
-		fastpathTV.DecMapStringInt64V(v, false, d)
-	case *map[string]int64:
-		var v2 map[string]int64
-		v2, changed = fastpathTV.DecMapStringInt64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[string]float32:
-		fastpathTV.DecMapStringFloat32V(v, false, d)
-	case *map[string]float32:
-		var v2 map[string]float32
-		v2, changed = fastpathTV.DecMapStringFloat32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint32V(rv.Interface().(map[int16]uint32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Uint32V(v map[int16]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[string]float64:
-		fastpathTV.DecMapStringFloat64V(v, false, d)
-	case *map[string]float64:
-		var v2 map[string]float64
-		v2, changed = fastpathTV.DecMapStringFloat64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int16(k2)]))
 		}
-	case map[string]bool:
-		fastpathTV.DecMapStringBoolV(v, false, d)
-	case *map[string]bool:
-		var v2 map[string]bool
-		v2, changed = fastpathTV.DecMapStringBoolV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[float32]interface{}:
-		fastpathTV.DecMapFloat32IntfV(v, false, d)
-	case *map[float32]interface{}:
-		var v2 map[float32]interface{}
-		v2, changed = fastpathTV.DecMapFloat32IntfV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint64V(rv.Interface().(map[int16]uint64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Uint64V(v map[int16]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float32]string:
-		fastpathTV.DecMapFloat32StringV(v, false, d)
-	case *map[float32]string:
-		var v2 map[float32]string
-		v2, changed = fastpathTV.DecMapFloat32StringV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int16(k2)]))
 		}
-	case map[float32]uint:
-		fastpathTV.DecMapFloat32UintV(v, false, d)
-	case *map[float32]uint:
-		var v2 map[float32]uint
-		v2, changed = fastpathTV.DecMapFloat32UintV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[float32]uint8:
-		fastpathTV.DecMapFloat32Uint8V(v, false, d)
-	case *map[float32]uint8:
-		var v2 map[float32]uint8
-		v2, changed = fastpathTV.DecMapFloat32Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapInt16UintptrV(rv.Interface().(map[int16]uintptr), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16UintptrV(v map[int16]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float32]uint16:
-		fastpathTV.DecMapFloat32Uint16V(v, false, d)
-	case *map[float32]uint16:
-		var v2 map[float32]uint16
-		v2, changed = fastpathTV.DecMapFloat32Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[int16(k2)])
 		}
-	case map[float32]uint32:
-		fastpathTV.DecMapFloat32Uint32V(v, false, d)
-	case *map[float32]uint32:
-		var v2 map[float32]uint32
-		v2, changed = fastpathTV.DecMapFloat32Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
-	case map[float32]uint64:
-		fastpathTV.DecMapFloat32Uint64V(v, false, d)
-	case *map[float32]uint64:
-		var v2 map[float32]uint64
-		v2, changed = fastpathTV.DecMapFloat32Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16IntR(rv reflect.Value) {
+	fastpathTV.EncMapInt16IntV(rv.Interface().(map[int16]int), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16IntV(v map[int16]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float32]uintptr:
-		fastpathTV.DecMapFloat32UintptrV(v, false, d)
-	case *map[float32]uintptr:
-		var v2 map[float32]uintptr
-		v2, changed = fastpathTV.DecMapFloat32UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int16(k2)]))
 		}
-	case map[float32]int:
-		fastpathTV.DecMapFloat32IntV(v, false, d)
-	case *map[float32]int:
-		var v2 map[float32]int
-		v2, changed = fastpathTV.DecMapFloat32IntV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[float32]int8:
-		fastpathTV.DecMapFloat32Int8V(v, false, d)
-	case *map[float32]int8:
-		var v2 map[float32]int8
-		v2, changed = fastpathTV.DecMapFloat32Int8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Int8R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Int8V(rv.Interface().(map[int16]int8), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Int8V(v map[int16]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float32]int16:
-		fastpathTV.DecMapFloat32Int16V(v, false, d)
-	case *map[float32]int16:
-		var v2 map[float32]int16
-		v2, changed = fastpathTV.DecMapFloat32Int16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int16(k2)]))
 		}
-	case map[float32]int32:
-		fastpathTV.DecMapFloat32Int32V(v, false, d)
-	case *map[float32]int32:
-		var v2 map[float32]int32
-		v2, changed = fastpathTV.DecMapFloat32Int32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[float32]int64:
-		fastpathTV.DecMapFloat32Int64V(v, false, d)
-	case *map[float32]int64:
-		var v2 map[float32]int64
-		v2, changed = fastpathTV.DecMapFloat32Int64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Int16R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Int16V(rv.Interface().(map[int16]int16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Int16V(v map[int16]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float32]float32:
-		fastpathTV.DecMapFloat32Float32V(v, false, d)
-	case *map[float32]float32:
-		var v2 map[float32]float32
-		v2, changed = fastpathTV.DecMapFloat32Float32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int16(k2)]))
 		}
-	case map[float32]float64:
-		fastpathTV.DecMapFloat32Float64V(v, false, d)
-	case *map[float32]float64:
-		var v2 map[float32]float64
-		v2, changed = fastpathTV.DecMapFloat32Float64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[float32]bool:
-		fastpathTV.DecMapFloat32BoolV(v, false, d)
-	case *map[float32]bool:
-		var v2 map[float32]bool
-		v2, changed = fastpathTV.DecMapFloat32BoolV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Int32R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Int32V(rv.Interface().(map[int16]int32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Int32V(v map[int16]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float64]interface{}:
-		fastpathTV.DecMapFloat64IntfV(v, false, d)
-	case *map[float64]interface{}:
-		var v2 map[float64]interface{}
-		v2, changed = fastpathTV.DecMapFloat64IntfV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int16(k2)]))
 		}
-	case map[float64]string:
-		fastpathTV.DecMapFloat64StringV(v, false, d)
-	case *map[float64]string:
-		var v2 map[float64]string
-		v2, changed = fastpathTV.DecMapFloat64StringV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[float64]uint:
-		fastpathTV.DecMapFloat64UintV(v, false, d)
-	case *map[float64]uint:
-		var v2 map[float64]uint
-		v2, changed = fastpathTV.DecMapFloat64UintV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Int64R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Int64V(rv.Interface().(map[int16]int64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Int64V(v map[int16]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float64]uint8:
-		fastpathTV.DecMapFloat64Uint8V(v, false, d)
-	case *map[float64]uint8:
-		var v2 map[float64]uint8
-		v2, changed = fastpathTV.DecMapFloat64Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int16(k2)]))
 		}
-	case map[float64]uint16:
-		fastpathTV.DecMapFloat64Uint16V(v, false, d)
-	case *map[float64]uint16:
-		var v2 map[float64]uint16
-		v2, changed = fastpathTV.DecMapFloat64Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[float64]uint32:
-		fastpathTV.DecMapFloat64Uint32V(v, false, d)
-	case *map[float64]uint32:
-		var v2 map[float64]uint32
-		v2, changed = fastpathTV.DecMapFloat64Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Float32R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Float32V(rv.Interface().(map[int16]float32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Float32V(v map[int16]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float64]uint64:
-		fastpathTV.DecMapFloat64Uint64V(v, false, d)
-	case *map[float64]uint64:
-		var v2 map[float64]uint64
-		v2, changed = fastpathTV.DecMapFloat64Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v[int16(k2)])
 		}
-	case map[float64]uintptr:
-		fastpathTV.DecMapFloat64UintptrV(v, false, d)
-	case *map[float64]uintptr:
-		var v2 map[float64]uintptr
-		v2, changed = fastpathTV.DecMapFloat64UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v2)
 		}
-	case map[float64]int:
-		fastpathTV.DecMapFloat64IntV(v, false, d)
-	case *map[float64]int:
-		var v2 map[float64]int
-		v2, changed = fastpathTV.DecMapFloat64IntV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16Float64R(rv reflect.Value) {
+	fastpathTV.EncMapInt16Float64V(rv.Interface().(map[int16]float64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16Float64V(v map[int16]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float64]int8:
-		fastpathTV.DecMapFloat64Int8V(v, false, d)
-	case *map[float64]int8:
-		var v2 map[float64]int8
-		v2, changed = fastpathTV.DecMapFloat64Int8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v[int16(k2)])
 		}
-	case map[float64]int16:
-		fastpathTV.DecMapFloat64Int16V(v, false, d)
-	case *map[float64]int16:
-		var v2 map[float64]int16
-		v2, changed = fastpathTV.DecMapFloat64Int16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v2)
 		}
-	case map[float64]int32:
-		fastpathTV.DecMapFloat64Int32V(v, false, d)
-	case *map[float64]int32:
-		var v2 map[float64]int32
-		v2, changed = fastpathTV.DecMapFloat64Int32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt16BoolR(rv reflect.Value) {
+	fastpathTV.EncMapInt16BoolV(rv.Interface().(map[int16]bool), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt16BoolV(v map[int16]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float64]int64:
-		fastpathTV.DecMapFloat64Int64V(v, false, d)
-	case *map[float64]int64:
-		var v2 map[float64]int64
-		v2, changed = fastpathTV.DecMapFloat64Int64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int16(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v[int16(k2)])
 		}
-	case map[float64]float32:
-		fastpathTV.DecMapFloat64Float32V(v, false, d)
-	case *map[float64]float32:
-		var v2 map[float64]float32
-		v2, changed = fastpathTV.DecMapFloat64Float32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v2)
 		}
-	case map[float64]float64:
-		fastpathTV.DecMapFloat64Float64V(v, false, d)
-	case *map[float64]float64:
-		var v2 map[float64]float64
-		v2, changed = fastpathTV.DecMapFloat64Float64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32IntfR(rv reflect.Value) {
+	fastpathTV.EncMapInt32IntfV(rv.Interface().(map[int32]interface{}), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32IntfV(v map[int32]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[float64]bool:
-		fastpathTV.DecMapFloat64BoolV(v, false, d)
-	case *map[float64]bool:
-		var v2 map[float64]bool
-		v2, changed = fastpathTV.DecMapFloat64BoolV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[int32(k2)])
 		}
-	case map[uint]interface{}:
-		fastpathTV.DecMapUintIntfV(v, false, d)
-	case *map[uint]interface{}:
-		var v2 map[uint]interface{}
-		v2, changed = fastpathTV.DecMapUintIntfV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
-	case map[uint]string:
-		fastpathTV.DecMapUintStringV(v, false, d)
-	case *map[uint]string:
-		var v2 map[uint]string
-		v2, changed = fastpathTV.DecMapUintStringV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32StringR(rv reflect.Value) {
+	fastpathTV.EncMapInt32StringV(rv.Interface().(map[int32]string), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32StringV(v map[int32]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint]uint:
-		fastpathTV.DecMapUintUintV(v, false, d)
-	case *map[uint]uint:
-		var v2 map[uint]uint
-		v2, changed = fastpathTV.DecMapUintUintV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeString(c_UTF8, v[int32(k2)])
 		}
-	case map[uint]uint8:
-		fastpathTV.DecMapUintUint8V(v, false, d)
-	case *map[uint]uint8:
-		var v2 map[uint]uint8
-		v2, changed = fastpathTV.DecMapUintUint8V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeString(c_UTF8, v2)
 		}
-	case map[uint]uint16:
-		fastpathTV.DecMapUintUint16V(v, false, d)
-	case *map[uint]uint16:
-		var v2 map[uint]uint16
-		v2, changed = fastpathTV.DecMapUintUint16V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32UintR(rv reflect.Value) {
+	fastpathTV.EncMapInt32UintV(rv.Interface().(map[int32]uint), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32UintV(v map[int32]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint]uint32:
-		fastpathTV.DecMapUintUint32V(v, false, d)
-	case *map[uint]uint32:
-		var v2 map[uint]uint32
-		v2, changed = fastpathTV.DecMapUintUint32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int32(k2)]))
 		}
-	case map[uint]uint64:
-		fastpathTV.DecMapUintUint64V(v, false, d)
-	case *map[uint]uint64:
-		var v2 map[uint]uint64
-		v2, changed = fastpathTV.DecMapUintUint64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint]uintptr:
-		fastpathTV.DecMapUintUintptrV(v, false, d)
-	case *map[uint]uintptr:
-		var v2 map[uint]uintptr
-		v2, changed = fastpathTV.DecMapUintUintptrV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint8V(rv.Interface().(map[int32]uint8), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Uint8V(v map[int32]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint]int:
-		fastpathTV.DecMapUintIntV(v, false, d)
-	case *map[uint]int:
-		var v2 map[uint]int
-		v2, changed = fastpathTV.DecMapUintIntV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int32(k2)]))
 		}
-	case map[uint]int8:
-		fastpathTV.DecMapUintInt8V(v, false, d)
-	case *map[uint]int8:
-		var v2 map[uint]int8
-		v2, changed = fastpathTV.DecMapUintInt8V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint]int16:
-		fastpathTV.DecMapUintInt16V(v, false, d)
-	case *map[uint]int16:
-		var v2 map[uint]int16
-		v2, changed = fastpathTV.DecMapUintInt16V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint16V(rv.Interface().(map[int32]uint16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Uint16V(v map[int32]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint]int32:
-		fastpathTV.DecMapUintInt32V(v, false, d)
-	case *map[uint]int32:
-		var v2 map[uint]int32
-		v2, changed = fastpathTV.DecMapUintInt32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int32(k2)]))
 		}
-	case map[uint]int64:
-		fastpathTV.DecMapUintInt64V(v, false, d)
-	case *map[uint]int64:
-		var v2 map[uint]int64
-		v2, changed = fastpathTV.DecMapUintInt64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint]float32:
-		fastpathTV.DecMapUintFloat32V(v, false, d)
-	case *map[uint]float32:
-		var v2 map[uint]float32
-		v2, changed = fastpathTV.DecMapUintFloat32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint32V(rv.Interface().(map[int32]uint32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Uint32V(v map[int32]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint]float64:
-		fastpathTV.DecMapUintFloat64V(v, false, d)
-	case *map[uint]float64:
-		var v2 map[uint]float64
-		v2, changed = fastpathTV.DecMapUintFloat64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int32(k2)]))
 		}
-	case map[uint]bool:
-		fastpathTV.DecMapUintBoolV(v, false, d)
-	case *map[uint]bool:
-		var v2 map[uint]bool
-		v2, changed = fastpathTV.DecMapUintBoolV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint8]interface{}:
-		fastpathTV.DecMapUint8IntfV(v, false, d)
-	case *map[uint8]interface{}:
-		var v2 map[uint8]interface{}
-		v2, changed = fastpathTV.DecMapUint8IntfV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint64V(rv.Interface().(map[int32]uint64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Uint64V(v map[int32]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint8]string:
-		fastpathTV.DecMapUint8StringV(v, false, d)
-	case *map[uint8]string:
-		var v2 map[uint8]string
-		v2, changed = fastpathTV.DecMapUint8StringV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int32(k2)]))
 		}
-	case map[uint8]uint:
-		fastpathTV.DecMapUint8UintV(v, false, d)
-	case *map[uint8]uint:
-		var v2 map[uint8]uint
-		v2, changed = fastpathTV.DecMapUint8UintV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint8]uint8:
-		fastpathTV.DecMapUint8Uint8V(v, false, d)
-	case *map[uint8]uint8:
-		var v2 map[uint8]uint8
-		v2, changed = fastpathTV.DecMapUint8Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapInt32UintptrV(rv.Interface().(map[int32]uintptr), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32UintptrV(v map[int32]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint8]uint16:
-		fastpathTV.DecMapUint8Uint16V(v, false, d)
-	case *map[uint8]uint16:
-		var v2 map[uint8]uint16
-		v2, changed = fastpathTV.DecMapUint8Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[int32(k2)])
 		}
-	case map[uint8]uint32:
-		fastpathTV.DecMapUint8Uint32V(v, false, d)
-	case *map[uint8]uint32:
-		var v2 map[uint8]uint32
-		v2, changed = fastpathTV.DecMapUint8Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
-	case map[uint8]uint64:
-		fastpathTV.DecMapUint8Uint64V(v, false, d)
-	case *map[uint8]uint64:
-		var v2 map[uint8]uint64
-		v2, changed = fastpathTV.DecMapUint8Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32IntR(rv reflect.Value) {
+	fastpathTV.EncMapInt32IntV(rv.Interface().(map[int32]int), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32IntV(v map[int32]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint8]uintptr:
-		fastpathTV.DecMapUint8UintptrV(v, false, d)
-	case *map[uint8]uintptr:
-		var v2 map[uint8]uintptr
-		v2, changed = fastpathTV.DecMapUint8UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int32(k2)]))
 		}
-	case map[uint8]int:
-		fastpathTV.DecMapUint8IntV(v, false, d)
-	case *map[uint8]int:
-		var v2 map[uint8]int
-		v2, changed = fastpathTV.DecMapUint8IntV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint8]int8:
-		fastpathTV.DecMapUint8Int8V(v, false, d)
-	case *map[uint8]int8:
-		var v2 map[uint8]int8
-		v2, changed = fastpathTV.DecMapUint8Int8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Int8R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Int8V(rv.Interface().(map[int32]int8), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Int8V(v map[int32]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint8]int16:
-		fastpathTV.DecMapUint8Int16V(v, false, d)
-	case *map[uint8]int16:
-		var v2 map[uint8]int16
-		v2, changed = fastpathTV.DecMapUint8Int16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int32(k2)]))
 		}
-	case map[uint8]int32:
-		fastpathTV.DecMapUint8Int32V(v, false, d)
-	case *map[uint8]int32:
-		var v2 map[uint8]int32
-		v2, changed = fastpathTV.DecMapUint8Int32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint8]int64:
-		fastpathTV.DecMapUint8Int64V(v, false, d)
-	case *map[uint8]int64:
-		var v2 map[uint8]int64
-		v2, changed = fastpathTV.DecMapUint8Int64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Int16R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Int16V(rv.Interface().(map[int32]int16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Int16V(v map[int32]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint8]float32:
-		fastpathTV.DecMapUint8Float32V(v, false, d)
-	case *map[uint8]float32:
-		var v2 map[uint8]float32
-		v2, changed = fastpathTV.DecMapUint8Float32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int32(k2)]))
 		}
-	case map[uint8]float64:
-		fastpathTV.DecMapUint8Float64V(v, false, d)
-	case *map[uint8]float64:
-		var v2 map[uint8]float64
-		v2, changed = fastpathTV.DecMapUint8Float64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint8]bool:
-		fastpathTV.DecMapUint8BoolV(v, false, d)
-	case *map[uint8]bool:
-		var v2 map[uint8]bool
-		v2, changed = fastpathTV.DecMapUint8BoolV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Int32R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Int32V(rv.Interface().(map[int32]int32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Int32V(v map[int32]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint16]interface{}:
-		fastpathTV.DecMapUint16IntfV(v, false, d)
-	case *map[uint16]interface{}:
-		var v2 map[uint16]interface{}
-		v2, changed = fastpathTV.DecMapUint16IntfV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int32(k2)]))
 		}
-	case map[uint16]string:
-		fastpathTV.DecMapUint16StringV(v, false, d)
-	case *map[uint16]string:
-		var v2 map[uint16]string
-		v2, changed = fastpathTV.DecMapUint16StringV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint16]uint:
-		fastpathTV.DecMapUint16UintV(v, false, d)
-	case *map[uint16]uint:
-		var v2 map[uint16]uint
-		v2, changed = fastpathTV.DecMapUint16UintV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Int64R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Int64V(rv.Interface().(map[int32]int64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint16]uint8:
-		fastpathTV.DecMapUint16Uint8V(v, false, d)
-	case *map[uint16]uint8:
-		var v2 map[uint16]uint8
-		v2, changed = fastpathTV.DecMapUint16Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int32(k2)]))
 		}
-	case map[uint16]uint16:
-		fastpathTV.DecMapUint16Uint16V(v, false, d)
-	case *map[uint16]uint16:
-		var v2 map[uint16]uint16
-		v2, changed = fastpathTV.DecMapUint16Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint16]uint32:
-		fastpathTV.DecMapUint16Uint32V(v, false, d)
-	case *map[uint16]uint32:
-		var v2 map[uint16]uint32
-		v2, changed = fastpathTV.DecMapUint16Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Float32R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Float32V(rv.Interface().(map[int32]float32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint16]uint64:
-		fastpathTV.DecMapUint16Uint64V(v, false, d)
-	case *map[uint16]uint64:
-		var v2 map[uint16]uint64
-		v2, changed = fastpathTV.DecMapUint16Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v[int32(k2)])
 		}
-	case map[uint16]uintptr:
-		fastpathTV.DecMapUint16UintptrV(v, false, d)
-	case *map[uint16]uintptr:
-		var v2 map[uint16]uintptr
-		v2, changed = fastpathTV.DecMapUint16UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v2)
 		}
-	case map[uint16]int:
-		fastpathTV.DecMapUint16IntV(v, false, d)
-	case *map[uint16]int:
-		var v2 map[uint16]int
-		v2, changed = fastpathTV.DecMapUint16IntV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32Float64R(rv reflect.Value) {
+	fastpathTV.EncMapInt32Float64V(rv.Interface().(map[int32]float64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint16]int8:
-		fastpathTV.DecMapUint16Int8V(v, false, d)
-	case *map[uint16]int8:
-		var v2 map[uint16]int8
-		v2, changed = fastpathTV.DecMapUint16Int8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v[int32(k2)])
 		}
-	case map[uint16]int16:
-		fastpathTV.DecMapUint16Int16V(v, false, d)
-	case *map[uint16]int16:
-		var v2 map[uint16]int16
-		v2, changed = fastpathTV.DecMapUint16Int16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v2)
 		}
-	case map[uint16]int32:
-		fastpathTV.DecMapUint16Int32V(v, false, d)
-	case *map[uint16]int32:
-		var v2 map[uint16]int32
-		v2, changed = fastpathTV.DecMapUint16Int32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt32BoolR(rv reflect.Value) {
+	fastpathTV.EncMapInt32BoolV(rv.Interface().(map[int32]bool), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint16]int64:
-		fastpathTV.DecMapUint16Int64V(v, false, d)
-	case *map[uint16]int64:
-		var v2 map[uint16]int64
-		v2, changed = fastpathTV.DecMapUint16Int64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int32(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v[int32(k2)])
 		}
-	case map[uint16]float32:
-		fastpathTV.DecMapUint16Float32V(v, false, d)
-	case *map[uint16]float32:
-		var v2 map[uint16]float32
-		v2, changed = fastpathTV.DecMapUint16Float32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v2)
 		}
-	case map[uint16]float64:
-		fastpathTV.DecMapUint16Float64V(v, false, d)
-	case *map[uint16]float64:
-		var v2 map[uint16]float64
-		v2, changed = fastpathTV.DecMapUint16Float64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64IntfR(rv reflect.Value) {
+	fastpathTV.EncMapInt64IntfV(rv.Interface().(map[int64]interface{}), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint16]bool:
-		fastpathTV.DecMapUint16BoolV(v, false, d)
-	case *map[uint16]bool:
-		var v2 map[uint16]bool
-		v2, changed = fastpathTV.DecMapUint16BoolV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[int64(k2)])
 		}
-	case map[uint32]interface{}:
-		fastpathTV.DecMapUint32IntfV(v, false, d)
-	case *map[uint32]interface{}:
-		var v2 map[uint32]interface{}
-		v2, changed = fastpathTV.DecMapUint32IntfV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
-	case map[uint32]string:
-		fastpathTV.DecMapUint32StringV(v, false, d)
-	case *map[uint32]string:
-		var v2 map[uint32]string
-		v2, changed = fastpathTV.DecMapUint32StringV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64StringR(rv reflect.Value) {
+	fastpathTV.EncMapInt64StringV(rv.Interface().(map[int64]string), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64StringV(v map[int64]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint32]uint:
-		fastpathTV.DecMapUint32UintV(v, false, d)
-	case *map[uint32]uint:
-		var v2 map[uint32]uint
-		v2, changed = fastpathTV.DecMapUint32UintV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeString(c_UTF8, v[int64(k2)])
 		}
-	case map[uint32]uint8:
-		fastpathTV.DecMapUint32Uint8V(v, false, d)
-	case *map[uint32]uint8:
-		var v2 map[uint32]uint8
-		v2, changed = fastpathTV.DecMapUint32Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeString(c_UTF8, v2)
 		}
-	case map[uint32]uint16:
-		fastpathTV.DecMapUint32Uint16V(v, false, d)
-	case *map[uint32]uint16:
-		var v2 map[uint32]uint16
-		v2, changed = fastpathTV.DecMapUint32Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64UintR(rv reflect.Value) {
+	fastpathTV.EncMapInt64UintV(rv.Interface().(map[int64]uint), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint32]uint32:
-		fastpathTV.DecMapUint32Uint32V(v, false, d)
-	case *map[uint32]uint32:
-		var v2 map[uint32]uint32
-		v2, changed = fastpathTV.DecMapUint32Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int64(k2)]))
 		}
-	case map[uint32]uint64:
-		fastpathTV.DecMapUint32Uint64V(v, false, d)
-	case *map[uint32]uint64:
-		var v2 map[uint32]uint64
-		v2, changed = fastpathTV.DecMapUint32Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint32]uintptr:
-		fastpathTV.DecMapUint32UintptrV(v, false, d)
-	case *map[uint32]uintptr:
-		var v2 map[uint32]uintptr
-		v2, changed = fastpathTV.DecMapUint32UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Uint8R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint8V(rv.Interface().(map[int64]uint8), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint32]int:
-		fastpathTV.DecMapUint32IntV(v, false, d)
-	case *map[uint32]int:
-		var v2 map[uint32]int
-		v2, changed = fastpathTV.DecMapUint32IntV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int64(k2)]))
 		}
-	case map[uint32]int8:
-		fastpathTV.DecMapUint32Int8V(v, false, d)
-	case *map[uint32]int8:
-		var v2 map[uint32]int8
-		v2, changed = fastpathTV.DecMapUint32Int8V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint32]int16:
-		fastpathTV.DecMapUint32Int16V(v, false, d)
-	case *map[uint32]int16:
-		var v2 map[uint32]int16
-		v2, changed = fastpathTV.DecMapUint32Int16V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Uint16R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint16V(rv.Interface().(map[int64]uint16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint32]int32:
-		fastpathTV.DecMapUint32Int32V(v, false, d)
-	case *map[uint32]int32:
-		var v2 map[uint32]int32
-		v2, changed = fastpathTV.DecMapUint32Int32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int64(k2)]))
 		}
-	case map[uint32]int64:
-		fastpathTV.DecMapUint32Int64V(v, false, d)
-	case *map[uint32]int64:
-		var v2 map[uint32]int64
-		v2, changed = fastpathTV.DecMapUint32Int64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint32]float32:
-		fastpathTV.DecMapUint32Float32V(v, false, d)
-	case *map[uint32]float32:
-		var v2 map[uint32]float32
-		v2, changed = fastpathTV.DecMapUint32Float32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Uint32R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint32V(rv.Interface().(map[int64]uint32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint32]float64:
-		fastpathTV.DecMapUint32Float64V(v, false, d)
-	case *map[uint32]float64:
-		var v2 map[uint32]float64
-		v2, changed = fastpathTV.DecMapUint32Float64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int64(k2)]))
 		}
-	case map[uint32]bool:
-		fastpathTV.DecMapUint32BoolV(v, false, d)
-	case *map[uint32]bool:
-		var v2 map[uint32]bool
-		v2, changed = fastpathTV.DecMapUint32BoolV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint64]interface{}:
-		fastpathTV.DecMapUint64IntfV(v, false, d)
-	case *map[uint64]interface{}:
-		var v2 map[uint64]interface{}
-		v2, changed = fastpathTV.DecMapUint64IntfV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Uint64R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint64V(rv.Interface().(map[int64]uint64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint64]string:
-		fastpathTV.DecMapUint64StringV(v, false, d)
-	case *map[uint64]string:
-		var v2 map[uint64]string
-		v2, changed = fastpathTV.DecMapUint64StringV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[int64(k2)]))
 		}
-	case map[uint64]uint:
-		fastpathTV.DecMapUint64UintV(v, false, d)
-	case *map[uint64]uint:
-		var v2 map[uint64]uint
-		v2, changed = fastpathTV.DecMapUint64UintV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[uint64]uint8:
-		fastpathTV.DecMapUint64Uint8V(v, false, d)
-	case *map[uint64]uint8:
-		var v2 map[uint64]uint8
-		v2, changed = fastpathTV.DecMapUint64Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64UintptrR(rv reflect.Value) {
+	fastpathTV.EncMapInt64UintptrV(rv.Interface().(map[int64]uintptr), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64UintptrV(v map[int64]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint64]uint16:
-		fastpathTV.DecMapUint64Uint16V(v, false, d)
-	case *map[uint64]uint16:
-		var v2 map[uint64]uint16
-		v2, changed = fastpathTV.DecMapUint64Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[int64(k2)])
 		}
-	case map[uint64]uint32:
-		fastpathTV.DecMapUint64Uint32V(v, false, d)
-	case *map[uint64]uint32:
-		var v2 map[uint64]uint32
-		v2, changed = fastpathTV.DecMapUint64Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
-	case map[uint64]uint64:
-		fastpathTV.DecMapUint64Uint64V(v, false, d)
-	case *map[uint64]uint64:
-		var v2 map[uint64]uint64
-		v2, changed = fastpathTV.DecMapUint64Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64IntR(rv reflect.Value) {
+	fastpathTV.EncMapInt64IntV(rv.Interface().(map[int64]int), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64IntV(v map[int64]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint64]uintptr:
-		fastpathTV.DecMapUint64UintptrV(v, false, d)
-	case *map[uint64]uintptr:
-		var v2 map[uint64]uintptr
-		v2, changed = fastpathTV.DecMapUint64UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int64(k2)]))
 		}
-	case map[uint64]int:
-		fastpathTV.DecMapUint64IntV(v, false, d)
-	case *map[uint64]int:
-		var v2 map[uint64]int
-		v2, changed = fastpathTV.DecMapUint64IntV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint64]int8:
-		fastpathTV.DecMapUint64Int8V(v, false, d)
-	case *map[uint64]int8:
-		var v2 map[uint64]int8
-		v2, changed = fastpathTV.DecMapUint64Int8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Int8R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Int8V(rv.Interface().(map[int64]int8), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint64]int16:
-		fastpathTV.DecMapUint64Int16V(v, false, d)
-	case *map[uint64]int16:
-		var v2 map[uint64]int16
-		v2, changed = fastpathTV.DecMapUint64Int16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int64(k2)]))
 		}
-	case map[uint64]int32:
-		fastpathTV.DecMapUint64Int32V(v, false, d)
-	case *map[uint64]int32:
-		var v2 map[uint64]int32
-		v2, changed = fastpathTV.DecMapUint64Int32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint64]int64:
-		fastpathTV.DecMapUint64Int64V(v, false, d)
-	case *map[uint64]int64:
-		var v2 map[uint64]int64
-		v2, changed = fastpathTV.DecMapUint64Int64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Int16R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Int16V(rv.Interface().(map[int64]int16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uint64]float32:
-		fastpathTV.DecMapUint64Float32V(v, false, d)
-	case *map[uint64]float32:
-		var v2 map[uint64]float32
-		v2, changed = fastpathTV.DecMapUint64Float32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int64(k2)]))
 		}
-	case map[uint64]float64:
-		fastpathTV.DecMapUint64Float64V(v, false, d)
-	case *map[uint64]float64:
-		var v2 map[uint64]float64
-		v2, changed = fastpathTV.DecMapUint64Float64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uint64]bool:
-		fastpathTV.DecMapUint64BoolV(v, false, d)
-	case *map[uint64]bool:
-		var v2 map[uint64]bool
-		v2, changed = fastpathTV.DecMapUint64BoolV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Int32R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Int32V(rv.Interface().(map[int64]int32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uintptr]interface{}:
-		fastpathTV.DecMapUintptrIntfV(v, false, d)
-	case *map[uintptr]interface{}:
-		var v2 map[uintptr]interface{}
-		v2, changed = fastpathTV.DecMapUintptrIntfV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int64(k2)]))
 		}
-	case map[uintptr]string:
-		fastpathTV.DecMapUintptrStringV(v, false, d)
-	case *map[uintptr]string:
-		var v2 map[uintptr]string
-		v2, changed = fastpathTV.DecMapUintptrStringV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uintptr]uint:
-		fastpathTV.DecMapUintptrUintV(v, false, d)
-	case *map[uintptr]uint:
-		var v2 map[uintptr]uint
-		v2, changed = fastpathTV.DecMapUintptrUintV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Int64R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Int64V(rv.Interface().(map[int64]int64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uintptr]uint8:
-		fastpathTV.DecMapUintptrUint8V(v, false, d)
-	case *map[uintptr]uint8:
-		var v2 map[uintptr]uint8
-		v2, changed = fastpathTV.DecMapUintptrUint8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[int64(k2)]))
 		}
-	case map[uintptr]uint16:
-		fastpathTV.DecMapUintptrUint16V(v, false, d)
-	case *map[uintptr]uint16:
-		var v2 map[uintptr]uint16
-		v2, changed = fastpathTV.DecMapUintptrUint16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[uintptr]uint32:
-		fastpathTV.DecMapUintptrUint32V(v, false, d)
-	case *map[uintptr]uint32:
-		var v2 map[uintptr]uint32
-		v2, changed = fastpathTV.DecMapUintptrUint32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Float32R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Float32V(rv.Interface().(map[int64]float32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uintptr]uint64:
-		fastpathTV.DecMapUintptrUint64V(v, false, d)
-	case *map[uintptr]uint64:
-		var v2 map[uintptr]uint64
-		v2, changed = fastpathTV.DecMapUintptrUint64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v[int64(k2)])
 		}
-	case map[uintptr]uintptr:
-		fastpathTV.DecMapUintptrUintptrV(v, false, d)
-	case *map[uintptr]uintptr:
-		var v2 map[uintptr]uintptr
-		v2, changed = fastpathTV.DecMapUintptrUintptrV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v2)
 		}
-	case map[uintptr]int:
-		fastpathTV.DecMapUintptrIntV(v, false, d)
-	case *map[uintptr]int:
-		var v2 map[uintptr]int
-		v2, changed = fastpathTV.DecMapUintptrIntV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64Float64R(rv reflect.Value) {
+	fastpathTV.EncMapInt64Float64V(rv.Interface().(map[int64]float64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uintptr]int8:
-		fastpathTV.DecMapUintptrInt8V(v, false, d)
-	case *map[uintptr]int8:
-		var v2 map[uintptr]int8
-		v2, changed = fastpathTV.DecMapUintptrInt8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v[int64(k2)])
 		}
-	case map[uintptr]int16:
-		fastpathTV.DecMapUintptrInt16V(v, false, d)
-	case *map[uintptr]int16:
-		var v2 map[uintptr]int16
-		v2, changed = fastpathTV.DecMapUintptrInt16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v2)
 		}
-	case map[uintptr]int32:
-		fastpathTV.DecMapUintptrInt32V(v, false, d)
-	case *map[uintptr]int32:
-		var v2 map[uintptr]int32
-		v2, changed = fastpathTV.DecMapUintptrInt32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapInt64BoolR(rv reflect.Value) {
+	fastpathTV.EncMapInt64BoolV(rv.Interface().(map[int64]bool), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
 		}
-	case map[uintptr]int64:
-		fastpathTV.DecMapUintptrInt64V(v, false, d)
-	case *map[uintptr]int64:
-		var v2 map[uintptr]int64
-		v2, changed = fastpathTV.DecMapUintptrInt64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(intSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(int64(k2)))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v[int64(k2)])
 		}
-	case map[uintptr]float32:
-		fastpathTV.DecMapUintptrFloat32V(v, false, d)
-	case *map[uintptr]float32:
-		var v2 map[uintptr]float32
-		v2, changed = fastpathTV.DecMapUintptrFloat32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeInt(int64(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v2)
 		}
-	case map[uintptr]float64:
-		fastpathTV.DecMapUintptrFloat64V(v, false, d)
-	case *map[uintptr]float64:
-		var v2 map[uintptr]float64
-		v2, changed = fastpathTV.DecMapUintptrFloat64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolIntfR(rv reflect.Value) {
+	fastpathTV.EncMapBoolIntfV(rv.Interface().(map[bool]interface{}), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolIntfV(v map[bool]interface{}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[uintptr]bool:
-		fastpathTV.DecMapUintptrBoolV(v, false, d)
-	case *map[uintptr]bool:
-		var v2 map[uintptr]bool
-		v2, changed = fastpathTV.DecMapUintptrBoolV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[bool(k2)])
 		}
-	case map[int]interface{}:
-		fastpathTV.DecMapIntIntfV(v, false, d)
-	case *map[int]interface{}:
-		var v2 map[int]interface{}
-		v2, changed = fastpathTV.DecMapIntIntfV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
-	case map[int]string:
-		fastpathTV.DecMapIntStringV(v, false, d)
-	case *map[int]string:
-		var v2 map[int]string
-		v2, changed = fastpathTV.DecMapIntStringV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolStringR(rv reflect.Value) {
+	fastpathTV.EncMapBoolStringV(rv.Interface().(map[bool]string), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolStringV(v map[bool]string, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int]uint:
-		fastpathTV.DecMapIntUintV(v, false, d)
-	case *map[int]uint:
-		var v2 map[int]uint
-		v2, changed = fastpathTV.DecMapIntUintV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeString(c_UTF8, v[bool(k2)])
 		}
-	case map[int]uint8:
-		fastpathTV.DecMapIntUint8V(v, false, d)
-	case *map[int]uint8:
-		var v2 map[int]uint8
-		v2, changed = fastpathTV.DecMapIntUint8V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeString(c_UTF8, v2)
 		}
-	case map[int]uint16:
-		fastpathTV.DecMapIntUint16V(v, false, d)
-	case *map[int]uint16:
-		var v2 map[int]uint16
-		v2, changed = fastpathTV.DecMapIntUint16V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolUintR(rv reflect.Value) {
+	fastpathTV.EncMapBoolUintV(rv.Interface().(map[bool]uint), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolUintV(v map[bool]uint, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int]uint32:
-		fastpathTV.DecMapIntUint32V(v, false, d)
-	case *map[int]uint32:
-		var v2 map[int]uint32
-		v2, changed = fastpathTV.DecMapIntUint32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[bool(k2)]))
 		}
-	case map[int]uint64:
-		fastpathTV.DecMapIntUint64V(v, false, d)
-	case *map[int]uint64:
-		var v2 map[int]uint64
-		v2, changed = fastpathTV.DecMapIntUint64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[int]uintptr:
-		fastpathTV.DecMapIntUintptrV(v, false, d)
-	case *map[int]uintptr:
-		var v2 map[int]uintptr
-		v2, changed = fastpathTV.DecMapIntUintptrV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolUint8R(rv reflect.Value) {
+	fastpathTV.EncMapBoolUint8V(rv.Interface().(map[bool]uint8), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolUint8V(v map[bool]uint8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int]int:
-		fastpathTV.DecMapIntIntV(v, false, d)
-	case *map[int]int:
-		var v2 map[int]int
-		v2, changed = fastpathTV.DecMapIntIntV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[bool(k2)]))
 		}
-	case map[int]int8:
-		fastpathTV.DecMapIntInt8V(v, false, d)
-	case *map[int]int8:
-		var v2 map[int]int8
-		v2, changed = fastpathTV.DecMapIntInt8V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[int]int16:
-		fastpathTV.DecMapIntInt16V(v, false, d)
-	case *map[int]int16:
-		var v2 map[int]int16
-		v2, changed = fastpathTV.DecMapIntInt16V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolUint16R(rv reflect.Value) {
+	fastpathTV.EncMapBoolUint16V(rv.Interface().(map[bool]uint16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolUint16V(v map[bool]uint16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int]int32:
-		fastpathTV.DecMapIntInt32V(v, false, d)
-	case *map[int]int32:
-		var v2 map[int]int32
-		v2, changed = fastpathTV.DecMapIntInt32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[bool(k2)]))
 		}
-	case map[int]int64:
-		fastpathTV.DecMapIntInt64V(v, false, d)
-	case *map[int]int64:
-		var v2 map[int]int64
-		v2, changed = fastpathTV.DecMapIntInt64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[int]float32:
-		fastpathTV.DecMapIntFloat32V(v, false, d)
-	case *map[int]float32:
-		var v2 map[int]float32
-		v2, changed = fastpathTV.DecMapIntFloat32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolUint32R(rv reflect.Value) {
+	fastpathTV.EncMapBoolUint32V(rv.Interface().(map[bool]uint32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolUint32V(v map[bool]uint32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int]float64:
-		fastpathTV.DecMapIntFloat64V(v, false, d)
-	case *map[int]float64:
-		var v2 map[int]float64
-		v2, changed = fastpathTV.DecMapIntFloat64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[bool(k2)]))
 		}
-	case map[int]bool:
-		fastpathTV.DecMapIntBoolV(v, false, d)
-	case *map[int]bool:
-		var v2 map[int]bool
-		v2, changed = fastpathTV.DecMapIntBoolV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[int8]interface{}:
-		fastpathTV.DecMapInt8IntfV(v, false, d)
-	case *map[int8]interface{}:
-		var v2 map[int8]interface{}
-		v2, changed = fastpathTV.DecMapInt8IntfV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolUint64R(rv reflect.Value) {
+	fastpathTV.EncMapBoolUint64V(rv.Interface().(map[bool]uint64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolUint64V(v map[bool]uint64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int8]string:
-		fastpathTV.DecMapInt8StringV(v, false, d)
-	case *map[int8]string:
-		var v2 map[int8]string
-		v2, changed = fastpathTV.DecMapInt8StringV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v[bool(k2)]))
 		}
-	case map[int8]uint:
-		fastpathTV.DecMapInt8UintV(v, false, d)
-	case *map[int8]uint:
-		var v2 map[int8]uint
-		v2, changed = fastpathTV.DecMapInt8UintV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeUint(uint64(v2))
 		}
-	case map[int8]uint8:
-		fastpathTV.DecMapInt8Uint8V(v, false, d)
-	case *map[int8]uint8:
-		var v2 map[int8]uint8
-		v2, changed = fastpathTV.DecMapInt8Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolUintptrR(rv reflect.Value) {
+	fastpathTV.EncMapBoolUintptrV(rv.Interface().(map[bool]uintptr), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolUintptrV(v map[bool]uintptr, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int8]uint16:
-		fastpathTV.DecMapInt8Uint16V(v, false, d)
-	case *map[int8]uint16:
-		var v2 map[int8]uint16
-		v2, changed = fastpathTV.DecMapInt8Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v[bool(k2)])
 		}
-	case map[int8]uint32:
-		fastpathTV.DecMapInt8Uint32V(v, false, d)
-	case *map[int8]uint32:
-		var v2 map[int8]uint32
-		v2, changed = fastpathTV.DecMapInt8Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			e.encode(v2)
 		}
-	case map[int8]uint64:
-		fastpathTV.DecMapInt8Uint64V(v, false, d)
-	case *map[int8]uint64:
-		var v2 map[int8]uint64
-		v2, changed = fastpathTV.DecMapInt8Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolIntR(rv reflect.Value) {
+	fastpathTV.EncMapBoolIntV(rv.Interface().(map[bool]int), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolIntV(v map[bool]int, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int8]uintptr:
-		fastpathTV.DecMapInt8UintptrV(v, false, d)
-	case *map[int8]uintptr:
-		var v2 map[int8]uintptr
-		v2, changed = fastpathTV.DecMapInt8UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[bool(k2)]))
 		}
-	case map[int8]int:
-		fastpathTV.DecMapInt8IntV(v, false, d)
-	case *map[int8]int:
-		var v2 map[int8]int
-		v2, changed = fastpathTV.DecMapInt8IntV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[int8]int8:
-		fastpathTV.DecMapInt8Int8V(v, false, d)
-	case *map[int8]int8:
-		var v2 map[int8]int8
-		v2, changed = fastpathTV.DecMapInt8Int8V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolInt8R(rv reflect.Value) {
+	fastpathTV.EncMapBoolInt8V(rv.Interface().(map[bool]int8), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolInt8V(v map[bool]int8, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int8]int16:
-		fastpathTV.DecMapInt8Int16V(v, false, d)
-	case *map[int8]int16:
-		var v2 map[int8]int16
-		v2, changed = fastpathTV.DecMapInt8Int16V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[bool(k2)]))
 		}
-	case map[int8]int32:
-		fastpathTV.DecMapInt8Int32V(v, false, d)
-	case *map[int8]int32:
-		var v2 map[int8]int32
-		v2, changed = fastpathTV.DecMapInt8Int32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[int8]int64:
-		fastpathTV.DecMapInt8Int64V(v, false, d)
-	case *map[int8]int64:
-		var v2 map[int8]int64
-		v2, changed = fastpathTV.DecMapInt8Int64V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolInt16R(rv reflect.Value) {
+	fastpathTV.EncMapBoolInt16V(rv.Interface().(map[bool]int16), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolInt16V(v map[bool]int16, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int8]float32:
-		fastpathTV.DecMapInt8Float32V(v, false, d)
-	case *map[int8]float32:
-		var v2 map[int8]float32
-		v2, changed = fastpathTV.DecMapInt8Float32V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[bool(k2)]))
 		}
-	case map[int8]float64:
-		fastpathTV.DecMapInt8Float64V(v, false, d)
-	case *map[int8]float64:
-		var v2 map[int8]float64
-		v2, changed = fastpathTV.DecMapInt8Float64V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[int8]bool:
-		fastpathTV.DecMapInt8BoolV(v, false, d)
-	case *map[int8]bool:
-		var v2 map[int8]bool
-		v2, changed = fastpathTV.DecMapInt8BoolV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolInt32R(rv reflect.Value) {
+	fastpathTV.EncMapBoolInt32V(rv.Interface().(map[bool]int32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolInt32V(v map[bool]int32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int16]interface{}:
-		fastpathTV.DecMapInt16IntfV(v, false, d)
-	case *map[int16]interface{}:
-		var v2 map[int16]interface{}
-		v2, changed = fastpathTV.DecMapInt16IntfV(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[bool(k2)]))
 		}
-	case map[int16]string:
-		fastpathTV.DecMapInt16StringV(v, false, d)
-	case *map[int16]string:
-		var v2 map[int16]string
-		v2, changed = fastpathTV.DecMapInt16StringV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[int16]uint:
-		fastpathTV.DecMapInt16UintV(v, false, d)
-	case *map[int16]uint:
-		var v2 map[int16]uint
-		v2, changed = fastpathTV.DecMapInt16UintV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolInt64R(rv reflect.Value) {
+	fastpathTV.EncMapBoolInt64V(rv.Interface().(map[bool]int64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolInt64V(v map[bool]int64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int16]uint8:
-		fastpathTV.DecMapInt16Uint8V(v, false, d)
-	case *map[int16]uint8:
-		var v2 map[int16]uint8
-		v2, changed = fastpathTV.DecMapInt16Uint8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v[bool(k2)]))
 		}
-	case map[int16]uint16:
-		fastpathTV.DecMapInt16Uint16V(v, false, d)
-	case *map[int16]uint16:
-		var v2 map[int16]uint16
-		v2, changed = fastpathTV.DecMapInt16Uint16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeInt(int64(v2))
 		}
-	case map[int16]uint32:
-		fastpathTV.DecMapInt16Uint32V(v, false, d)
-	case *map[int16]uint32:
-		var v2 map[int16]uint32
-		v2, changed = fastpathTV.DecMapInt16Uint32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolFloat32R(rv reflect.Value) {
+	fastpathTV.EncMapBoolFloat32V(rv.Interface().(map[bool]float32), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolFloat32V(v map[bool]float32, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int16]uint64:
-		fastpathTV.DecMapInt16Uint64V(v, false, d)
-	case *map[int16]uint64:
-		var v2 map[int16]uint64
-		v2, changed = fastpathTV.DecMapInt16Uint64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v[bool(k2)])
 		}
-	case map[int16]uintptr:
-		fastpathTV.DecMapInt16UintptrV(v, false, d)
-	case *map[int16]uintptr:
-		var v2 map[int16]uintptr
-		v2, changed = fastpathTV.DecMapInt16UintptrV(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat32(v2)
 		}
-	case map[int16]int:
-		fastpathTV.DecMapInt16IntV(v, false, d)
-	case *map[int16]int:
-		var v2 map[int16]int
-		v2, changed = fastpathTV.DecMapInt16IntV(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolFloat64R(rv reflect.Value) {
+	fastpathTV.EncMapBoolFloat64V(rv.Interface().(map[bool]float64), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolFloat64V(v map[bool]float64, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int16]int8:
-		fastpathTV.DecMapInt16Int8V(v, false, d)
-	case *map[int16]int8:
-		var v2 map[int16]int8
-		v2, changed = fastpathTV.DecMapInt16Int8V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v[bool(k2)])
 		}
-	case map[int16]int16:
-		fastpathTV.DecMapInt16Int16V(v, false, d)
-	case *map[int16]int16:
-		var v2 map[int16]int16
-		v2, changed = fastpathTV.DecMapInt16Int16V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeFloat64(v2)
 		}
-	case map[int16]int32:
-		fastpathTV.DecMapInt16Int32V(v, false, d)
-	case *map[int16]int32:
-		var v2 map[int16]int32
-		v2, changed = fastpathTV.DecMapInt16Int32V(*v, true, d)
-		if changed {
-			*v = v2
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+func (f *encFnInfo) fastpathEncMapBoolBoolR(rv reflect.Value) {
+	fastpathTV.EncMapBoolBoolV(rv.Interface().(map[bool]bool), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
 		}
-	case map[int16]int64:
-		fastpathTV.DecMapInt16Int64V(v, false, d)
-	case *map[int16]int64:
-		var v2 map[int16]int64
-		v2, changed = fastpathTV.DecMapInt16Int64V(*v, true, d)
-		if changed {
-			*v = v2
+		sort.Sort(boolSlice(v2))
+		for _, k2 := range v2 {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(bool(k2))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v[bool(k2)])
 		}
-	case map[int16]float32:
-		fastpathTV.DecMapInt16Float32V(v, false, d)
-	case *map[int16]float32:
-		var v2 map[int16]float32
-		v2, changed = fastpathTV.DecMapInt16Float32V(*v, true, d)
-		if changed {
-			*v = v2
+	} else {
+		for k2, v2 := range v {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			ee.EncodeBool(k2)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			ee.EncodeBool(v2)
 		}
-	case map[int16]float64:
-		fastpathTV.DecMapInt16Float64V(v, false, d)
-	case *map[int16]float64:
-		var v2 map[int16]float64
-		v2, changed = fastpathTV.DecMapInt16Float64V(*v, true, d)
-		if changed {
+	}
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
+}
+
+// -- decode
+
+// -- -- fast path type switch
+func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
+	switch v := iv.(type) {
+
+	case []interface{}:
+		fastpathTV.DecSliceIntfV(v, fastpathCheckNilFalse, false, d)
+	case *[]interface{}:
+		v2, changed2 := fastpathTV.DecSliceIntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int16]bool:
-		fastpathTV.DecMapInt16BoolV(v, false, d)
-	case *map[int16]bool:
-		var v2 map[int16]bool
-		v2, changed = fastpathTV.DecMapInt16BoolV(*v, true, d)
-		if changed {
+
+	case map[interface{}]interface{}:
+		fastpathTV.DecMapIntfIntfV(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]interface{}:
+		v2, changed2 := fastpathTV.DecMapIntfIntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]interface{}:
-		fastpathTV.DecMapInt32IntfV(v, false, d)
-	case *map[int32]interface{}:
-		var v2 map[int32]interface{}
-		v2, changed = fastpathTV.DecMapInt32IntfV(*v, true, d)
-		if changed {
+
+	case map[interface{}]string:
+		fastpathTV.DecMapIntfStringV(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]string:
+		v2, changed2 := fastpathTV.DecMapIntfStringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]string:
-		fastpathTV.DecMapInt32StringV(v, false, d)
-	case *map[int32]string:
-		var v2 map[int32]string
-		v2, changed = fastpathTV.DecMapInt32StringV(*v, true, d)
-		if changed {
+
+	case map[interface{}]uint:
+		fastpathTV.DecMapIntfUintV(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]uint:
+		v2, changed2 := fastpathTV.DecMapIntfUintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]uint:
-		fastpathTV.DecMapInt32UintV(v, false, d)
-	case *map[int32]uint:
-		var v2 map[int32]uint
-		v2, changed = fastpathTV.DecMapInt32UintV(*v, true, d)
-		if changed {
+
+	case map[interface{}]uint8:
+		fastpathTV.DecMapIntfUint8V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]uint8:
+		v2, changed2 := fastpathTV.DecMapIntfUint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]uint8:
-		fastpathTV.DecMapInt32Uint8V(v, false, d)
-	case *map[int32]uint8:
-		var v2 map[int32]uint8
-		v2, changed = fastpathTV.DecMapInt32Uint8V(*v, true, d)
-		if changed {
+
+	case map[interface{}]uint16:
+		fastpathTV.DecMapIntfUint16V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]uint16:
+		v2, changed2 := fastpathTV.DecMapIntfUint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]uint16:
-		fastpathTV.DecMapInt32Uint16V(v, false, d)
-	case *map[int32]uint16:
-		var v2 map[int32]uint16
-		v2, changed = fastpathTV.DecMapInt32Uint16V(*v, true, d)
-		if changed {
+
+	case map[interface{}]uint32:
+		fastpathTV.DecMapIntfUint32V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]uint32:
+		v2, changed2 := fastpathTV.DecMapIntfUint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]uint32:
-		fastpathTV.DecMapInt32Uint32V(v, false, d)
-	case *map[int32]uint32:
-		var v2 map[int32]uint32
-		v2, changed = fastpathTV.DecMapInt32Uint32V(*v, true, d)
-		if changed {
+
+	case map[interface{}]uint64:
+		fastpathTV.DecMapIntfUint64V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]uint64:
+		v2, changed2 := fastpathTV.DecMapIntfUint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]uint64:
-		fastpathTV.DecMapInt32Uint64V(v, false, d)
-	case *map[int32]uint64:
-		var v2 map[int32]uint64
-		v2, changed = fastpathTV.DecMapInt32Uint64V(*v, true, d)
-		if changed {
+
+	case map[interface{}]uintptr:
+		fastpathTV.DecMapIntfUintptrV(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]uintptr:
+		v2, changed2 := fastpathTV.DecMapIntfUintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]uintptr:
-		fastpathTV.DecMapInt32UintptrV(v, false, d)
-	case *map[int32]uintptr:
-		var v2 map[int32]uintptr
-		v2, changed = fastpathTV.DecMapInt32UintptrV(*v, true, d)
-		if changed {
+
+	case map[interface{}]int:
+		fastpathTV.DecMapIntfIntV(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]int:
+		v2, changed2 := fastpathTV.DecMapIntfIntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]int:
-		fastpathTV.DecMapInt32IntV(v, false, d)
-	case *map[int32]int:
-		var v2 map[int32]int
-		v2, changed = fastpathTV.DecMapInt32IntV(*v, true, d)
-		if changed {
+
+	case map[interface{}]int8:
+		fastpathTV.DecMapIntfInt8V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]int8:
+		v2, changed2 := fastpathTV.DecMapIntfInt8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]int8:
-		fastpathTV.DecMapInt32Int8V(v, false, d)
-	case *map[int32]int8:
-		var v2 map[int32]int8
-		v2, changed = fastpathTV.DecMapInt32Int8V(*v, true, d)
-		if changed {
+
+	case map[interface{}]int16:
+		fastpathTV.DecMapIntfInt16V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]int16:
+		v2, changed2 := fastpathTV.DecMapIntfInt16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]int16:
-		fastpathTV.DecMapInt32Int16V(v, false, d)
-	case *map[int32]int16:
-		var v2 map[int32]int16
-		v2, changed = fastpathTV.DecMapInt32Int16V(*v, true, d)
-		if changed {
+
+	case map[interface{}]int32:
+		fastpathTV.DecMapIntfInt32V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]int32:
+		v2, changed2 := fastpathTV.DecMapIntfInt32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]int32:
-		fastpathTV.DecMapInt32Int32V(v, false, d)
-	case *map[int32]int32:
-		var v2 map[int32]int32
-		v2, changed = fastpathTV.DecMapInt32Int32V(*v, true, d)
-		if changed {
+
+	case map[interface{}]int64:
+		fastpathTV.DecMapIntfInt64V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]int64:
+		v2, changed2 := fastpathTV.DecMapIntfInt64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]int64:
-		fastpathTV.DecMapInt32Int64V(v, false, d)
-	case *map[int32]int64:
-		var v2 map[int32]int64
-		v2, changed = fastpathTV.DecMapInt32Int64V(*v, true, d)
-		if changed {
+
+	case map[interface{}]float32:
+		fastpathTV.DecMapIntfFloat32V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]float32:
+		v2, changed2 := fastpathTV.DecMapIntfFloat32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]float32:
-		fastpathTV.DecMapInt32Float32V(v, false, d)
-	case *map[int32]float32:
-		var v2 map[int32]float32
-		v2, changed = fastpathTV.DecMapInt32Float32V(*v, true, d)
-		if changed {
+
+	case map[interface{}]float64:
+		fastpathTV.DecMapIntfFloat64V(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]float64:
+		v2, changed2 := fastpathTV.DecMapIntfFloat64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]float64:
-		fastpathTV.DecMapInt32Float64V(v, false, d)
-	case *map[int32]float64:
-		var v2 map[int32]float64
-		v2, changed = fastpathTV.DecMapInt32Float64V(*v, true, d)
-		if changed {
+
+	case map[interface{}]bool:
+		fastpathTV.DecMapIntfBoolV(v, fastpathCheckNilFalse, false, d)
+	case *map[interface{}]bool:
+		v2, changed2 := fastpathTV.DecMapIntfBoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int32]bool:
-		fastpathTV.DecMapInt32BoolV(v, false, d)
-	case *map[int32]bool:
-		var v2 map[int32]bool
-		v2, changed = fastpathTV.DecMapInt32BoolV(*v, true, d)
-		if changed {
+
+	case []string:
+		fastpathTV.DecSliceStringV(v, fastpathCheckNilFalse, false, d)
+	case *[]string:
+		v2, changed2 := fastpathTV.DecSliceStringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]interface{}:
-		fastpathTV.DecMapInt64IntfV(v, false, d)
-	case *map[int64]interface{}:
-		var v2 map[int64]interface{}
-		v2, changed = fastpathTV.DecMapInt64IntfV(*v, true, d)
-		if changed {
+
+	case map[string]interface{}:
+		fastpathTV.DecMapStringIntfV(v, fastpathCheckNilFalse, false, d)
+	case *map[string]interface{}:
+		v2, changed2 := fastpathTV.DecMapStringIntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]string:
-		fastpathTV.DecMapInt64StringV(v, false, d)
-	case *map[int64]string:
-		var v2 map[int64]string
-		v2, changed = fastpathTV.DecMapInt64StringV(*v, true, d)
-		if changed {
+
+	case map[string]string:
+		fastpathTV.DecMapStringStringV(v, fastpathCheckNilFalse, false, d)
+	case *map[string]string:
+		v2, changed2 := fastpathTV.DecMapStringStringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]uint:
-		fastpathTV.DecMapInt64UintV(v, false, d)
-	case *map[int64]uint:
-		var v2 map[int64]uint
-		v2, changed = fastpathTV.DecMapInt64UintV(*v, true, d)
-		if changed {
+
+	case map[string]uint:
+		fastpathTV.DecMapStringUintV(v, fastpathCheckNilFalse, false, d)
+	case *map[string]uint:
+		v2, changed2 := fastpathTV.DecMapStringUintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]uint8:
-		fastpathTV.DecMapInt64Uint8V(v, false, d)
-	case *map[int64]uint8:
-		var v2 map[int64]uint8
-		v2, changed = fastpathTV.DecMapInt64Uint8V(*v, true, d)
-		if changed {
+
+	case map[string]uint8:
+		fastpathTV.DecMapStringUint8V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]uint8:
+		v2, changed2 := fastpathTV.DecMapStringUint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]uint16:
-		fastpathTV.DecMapInt64Uint16V(v, false, d)
-	case *map[int64]uint16:
-		var v2 map[int64]uint16
-		v2, changed = fastpathTV.DecMapInt64Uint16V(*v, true, d)
-		if changed {
+
+	case map[string]uint16:
+		fastpathTV.DecMapStringUint16V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]uint16:
+		v2, changed2 := fastpathTV.DecMapStringUint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]uint32:
-		fastpathTV.DecMapInt64Uint32V(v, false, d)
-	case *map[int64]uint32:
-		var v2 map[int64]uint32
-		v2, changed = fastpathTV.DecMapInt64Uint32V(*v, true, d)
-		if changed {
+
+	case map[string]uint32:
+		fastpathTV.DecMapStringUint32V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]uint32:
+		v2, changed2 := fastpathTV.DecMapStringUint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]uint64:
-		fastpathTV.DecMapInt64Uint64V(v, false, d)
-	case *map[int64]uint64:
-		var v2 map[int64]uint64
-		v2, changed = fastpathTV.DecMapInt64Uint64V(*v, true, d)
-		if changed {
+
+	case map[string]uint64:
+		fastpathTV.DecMapStringUint64V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]uint64:
+		v2, changed2 := fastpathTV.DecMapStringUint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]uintptr:
-		fastpathTV.DecMapInt64UintptrV(v, false, d)
-	case *map[int64]uintptr:
-		var v2 map[int64]uintptr
-		v2, changed = fastpathTV.DecMapInt64UintptrV(*v, true, d)
-		if changed {
+
+	case map[string]uintptr:
+		fastpathTV.DecMapStringUintptrV(v, fastpathCheckNilFalse, false, d)
+	case *map[string]uintptr:
+		v2, changed2 := fastpathTV.DecMapStringUintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]int:
-		fastpathTV.DecMapInt64IntV(v, false, d)
-	case *map[int64]int:
-		var v2 map[int64]int
-		v2, changed = fastpathTV.DecMapInt64IntV(*v, true, d)
-		if changed {
+
+	case map[string]int:
+		fastpathTV.DecMapStringIntV(v, fastpathCheckNilFalse, false, d)
+	case *map[string]int:
+		v2, changed2 := fastpathTV.DecMapStringIntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]int8:
-		fastpathTV.DecMapInt64Int8V(v, false, d)
-	case *map[int64]int8:
-		var v2 map[int64]int8
-		v2, changed = fastpathTV.DecMapInt64Int8V(*v, true, d)
-		if changed {
+
+	case map[string]int8:
+		fastpathTV.DecMapStringInt8V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]int8:
+		v2, changed2 := fastpathTV.DecMapStringInt8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]int16:
-		fastpathTV.DecMapInt64Int16V(v, false, d)
-	case *map[int64]int16:
-		var v2 map[int64]int16
-		v2, changed = fastpathTV.DecMapInt64Int16V(*v, true, d)
-		if changed {
+
+	case map[string]int16:
+		fastpathTV.DecMapStringInt16V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]int16:
+		v2, changed2 := fastpathTV.DecMapStringInt16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]int32:
-		fastpathTV.DecMapInt64Int32V(v, false, d)
-	case *map[int64]int32:
-		var v2 map[int64]int32
-		v2, changed = fastpathTV.DecMapInt64Int32V(*v, true, d)
-		if changed {
+
+	case map[string]int32:
+		fastpathTV.DecMapStringInt32V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]int32:
+		v2, changed2 := fastpathTV.DecMapStringInt32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]int64:
-		fastpathTV.DecMapInt64Int64V(v, false, d)
-	case *map[int64]int64:
-		var v2 map[int64]int64
-		v2, changed = fastpathTV.DecMapInt64Int64V(*v, true, d)
-		if changed {
+
+	case map[string]int64:
+		fastpathTV.DecMapStringInt64V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]int64:
+		v2, changed2 := fastpathTV.DecMapStringInt64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]float32:
-		fastpathTV.DecMapInt64Float32V(v, false, d)
-	case *map[int64]float32:
-		var v2 map[int64]float32
-		v2, changed = fastpathTV.DecMapInt64Float32V(*v, true, d)
-		if changed {
+
+	case map[string]float32:
+		fastpathTV.DecMapStringFloat32V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]float32:
+		v2, changed2 := fastpathTV.DecMapStringFloat32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]float64:
-		fastpathTV.DecMapInt64Float64V(v, false, d)
-	case *map[int64]float64:
-		var v2 map[int64]float64
-		v2, changed = fastpathTV.DecMapInt64Float64V(*v, true, d)
-		if changed {
+
+	case map[string]float64:
+		fastpathTV.DecMapStringFloat64V(v, fastpathCheckNilFalse, false, d)
+	case *map[string]float64:
+		v2, changed2 := fastpathTV.DecMapStringFloat64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[int64]bool:
-		fastpathTV.DecMapInt64BoolV(v, false, d)
-	case *map[int64]bool:
-		var v2 map[int64]bool
-		v2, changed = fastpathTV.DecMapInt64BoolV(*v, true, d)
-		if changed {
+
+	case map[string]bool:
+		fastpathTV.DecMapStringBoolV(v, fastpathCheckNilFalse, false, d)
+	case *map[string]bool:
+		v2, changed2 := fastpathTV.DecMapStringBoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]interface{}:
-		fastpathTV.DecMapBoolIntfV(v, false, d)
-	case *map[bool]interface{}:
-		var v2 map[bool]interface{}
-		v2, changed = fastpathTV.DecMapBoolIntfV(*v, true, d)
-		if changed {
+
+	case []float32:
+		fastpathTV.DecSliceFloat32V(v, fastpathCheckNilFalse, false, d)
+	case *[]float32:
+		v2, changed2 := fastpathTV.DecSliceFloat32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]string:
-		fastpathTV.DecMapBoolStringV(v, false, d)
-	case *map[bool]string:
-		var v2 map[bool]string
-		v2, changed = fastpathTV.DecMapBoolStringV(*v, true, d)
-		if changed {
+
+	case map[float32]interface{}:
+		fastpathTV.DecMapFloat32IntfV(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]interface{}:
+		v2, changed2 := fastpathTV.DecMapFloat32IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]uint:
-		fastpathTV.DecMapBoolUintV(v, false, d)
-	case *map[bool]uint:
-		var v2 map[bool]uint
-		v2, changed = fastpathTV.DecMapBoolUintV(*v, true, d)
-		if changed {
+
+	case map[float32]string:
+		fastpathTV.DecMapFloat32StringV(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]string:
+		v2, changed2 := fastpathTV.DecMapFloat32StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]uint8:
-		fastpathTV.DecMapBoolUint8V(v, false, d)
-	case *map[bool]uint8:
-		var v2 map[bool]uint8
-		v2, changed = fastpathTV.DecMapBoolUint8V(*v, true, d)
-		if changed {
+
+	case map[float32]uint:
+		fastpathTV.DecMapFloat32UintV(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]uint:
+		v2, changed2 := fastpathTV.DecMapFloat32UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]uint16:
-		fastpathTV.DecMapBoolUint16V(v, false, d)
-	case *map[bool]uint16:
-		var v2 map[bool]uint16
-		v2, changed = fastpathTV.DecMapBoolUint16V(*v, true, d)
-		if changed {
+
+	case map[float32]uint8:
+		fastpathTV.DecMapFloat32Uint8V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]uint8:
+		v2, changed2 := fastpathTV.DecMapFloat32Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]uint32:
-		fastpathTV.DecMapBoolUint32V(v, false, d)
-	case *map[bool]uint32:
-		var v2 map[bool]uint32
-		v2, changed = fastpathTV.DecMapBoolUint32V(*v, true, d)
-		if changed {
+
+	case map[float32]uint16:
+		fastpathTV.DecMapFloat32Uint16V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]uint16:
+		v2, changed2 := fastpathTV.DecMapFloat32Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]uint64:
-		fastpathTV.DecMapBoolUint64V(v, false, d)
-	case *map[bool]uint64:
-		var v2 map[bool]uint64
-		v2, changed = fastpathTV.DecMapBoolUint64V(*v, true, d)
-		if changed {
+
+	case map[float32]uint32:
+		fastpathTV.DecMapFloat32Uint32V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]uint32:
+		v2, changed2 := fastpathTV.DecMapFloat32Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]uintptr:
-		fastpathTV.DecMapBoolUintptrV(v, false, d)
-	case *map[bool]uintptr:
-		var v2 map[bool]uintptr
-		v2, changed = fastpathTV.DecMapBoolUintptrV(*v, true, d)
-		if changed {
+
+	case map[float32]uint64:
+		fastpathTV.DecMapFloat32Uint64V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]uint64:
+		v2, changed2 := fastpathTV.DecMapFloat32Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]int:
-		fastpathTV.DecMapBoolIntV(v, false, d)
-	case *map[bool]int:
-		var v2 map[bool]int
-		v2, changed = fastpathTV.DecMapBoolIntV(*v, true, d)
-		if changed {
+
+	case map[float32]uintptr:
+		fastpathTV.DecMapFloat32UintptrV(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]uintptr:
+		v2, changed2 := fastpathTV.DecMapFloat32UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]int8:
-		fastpathTV.DecMapBoolInt8V(v, false, d)
-	case *map[bool]int8:
-		var v2 map[bool]int8
-		v2, changed = fastpathTV.DecMapBoolInt8V(*v, true, d)
-		if changed {
+
+	case map[float32]int:
+		fastpathTV.DecMapFloat32IntV(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]int:
+		v2, changed2 := fastpathTV.DecMapFloat32IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]int16:
-		fastpathTV.DecMapBoolInt16V(v, false, d)
-	case *map[bool]int16:
-		var v2 map[bool]int16
-		v2, changed = fastpathTV.DecMapBoolInt16V(*v, true, d)
-		if changed {
+
+	case map[float32]int8:
+		fastpathTV.DecMapFloat32Int8V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]int8:
+		v2, changed2 := fastpathTV.DecMapFloat32Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]int32:
-		fastpathTV.DecMapBoolInt32V(v, false, d)
-	case *map[bool]int32:
-		var v2 map[bool]int32
-		v2, changed = fastpathTV.DecMapBoolInt32V(*v, true, d)
-		if changed {
+
+	case map[float32]int16:
+		fastpathTV.DecMapFloat32Int16V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]int16:
+		v2, changed2 := fastpathTV.DecMapFloat32Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]int64:
-		fastpathTV.DecMapBoolInt64V(v, false, d)
-	case *map[bool]int64:
-		var v2 map[bool]int64
-		v2, changed = fastpathTV.DecMapBoolInt64V(*v, true, d)
-		if changed {
+
+	case map[float32]int32:
+		fastpathTV.DecMapFloat32Int32V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]int32:
+		v2, changed2 := fastpathTV.DecMapFloat32Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]float32:
-		fastpathTV.DecMapBoolFloat32V(v, false, d)
-	case *map[bool]float32:
-		var v2 map[bool]float32
-		v2, changed = fastpathTV.DecMapBoolFloat32V(*v, true, d)
-		if changed {
+
+	case map[float32]int64:
+		fastpathTV.DecMapFloat32Int64V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]int64:
+		v2, changed2 := fastpathTV.DecMapFloat32Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]float64:
-		fastpathTV.DecMapBoolFloat64V(v, false, d)
-	case *map[bool]float64:
-		var v2 map[bool]float64
-		v2, changed = fastpathTV.DecMapBoolFloat64V(*v, true, d)
-		if changed {
+
+	case map[float32]float32:
+		fastpathTV.DecMapFloat32Float32V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]float32:
+		v2, changed2 := fastpathTV.DecMapFloat32Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	case map[bool]bool:
-		fastpathTV.DecMapBoolBoolV(v, false, d)
-	case *map[bool]bool:
-		var v2 map[bool]bool
-		v2, changed = fastpathTV.DecMapBoolBoolV(*v, true, d)
-		if changed {
+
+	case map[float32]float64:
+		fastpathTV.DecMapFloat32Float64V(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]float64:
+		v2, changed2 := fastpathTV.DecMapFloat32Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
 			*v = v2
 		}
-	default:
-		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
 
-func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
-	switch v := iv.(type) {
+	case map[float32]bool:
+		fastpathTV.DecMapFloat32BoolV(v, fastpathCheckNilFalse, false, d)
+	case *map[float32]bool:
+		v2, changed2 := fastpathTV.DecMapFloat32BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
 
-	case *[]interface{}:
-		*v = nil
-	case *[]string:
-		*v = nil
-	case *[]float32:
-		*v = nil
+	case []float64:
+		fastpathTV.DecSliceFloat64V(v, fastpathCheckNilFalse, false, d)
 	case *[]float64:
-		*v = nil
-	case *[]uint:
-		*v = nil
-	case *[]uint8:
-		*v = nil
-	case *[]uint16:
-		*v = nil
-	case *[]uint32:
-		*v = nil
-	case *[]uint64:
-		*v = nil
-	case *[]uintptr:
-		*v = nil
-	case *[]int:
-		*v = nil
-	case *[]int8:
-		*v = nil
-	case *[]int16:
-		*v = nil
-	case *[]int32:
-		*v = nil
-	case *[]int64:
-		*v = nil
-	case *[]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecSliceFloat64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
 
-	case *map[interface{}]interface{}:
-		*v = nil
-	case *map[interface{}]string:
-		*v = nil
-	case *map[interface{}]uint:
-		*v = nil
-	case *map[interface{}]uint8:
-		*v = nil
-	case *map[interface{}]uint16:
-		*v = nil
-	case *map[interface{}]uint32:
-		*v = nil
-	case *map[interface{}]uint64:
-		*v = nil
-	case *map[interface{}]uintptr:
-		*v = nil
-	case *map[interface{}]int:
-		*v = nil
-	case *map[interface{}]int8:
-		*v = nil
-	case *map[interface{}]int16:
-		*v = nil
-	case *map[interface{}]int32:
-		*v = nil
-	case *map[interface{}]int64:
-		*v = nil
-	case *map[interface{}]float32:
-		*v = nil
-	case *map[interface{}]float64:
-		*v = nil
-	case *map[interface{}]bool:
-		*v = nil
-	case *map[string]interface{}:
-		*v = nil
-	case *map[string]string:
-		*v = nil
-	case *map[string]uint:
-		*v = nil
-	case *map[string]uint8:
-		*v = nil
-	case *map[string]uint16:
-		*v = nil
-	case *map[string]uint32:
-		*v = nil
-	case *map[string]uint64:
-		*v = nil
-	case *map[string]uintptr:
-		*v = nil
-	case *map[string]int:
-		*v = nil
-	case *map[string]int8:
-		*v = nil
-	case *map[string]int16:
-		*v = nil
-	case *map[string]int32:
-		*v = nil
-	case *map[string]int64:
-		*v = nil
-	case *map[string]float32:
-		*v = nil
-	case *map[string]float64:
-		*v = nil
-	case *map[string]bool:
-		*v = nil
-	case *map[float32]interface{}:
-		*v = nil
-	case *map[float32]string:
-		*v = nil
-	case *map[float32]uint:
-		*v = nil
-	case *map[float32]uint8:
-		*v = nil
-	case *map[float32]uint16:
-		*v = nil
-	case *map[float32]uint32:
-		*v = nil
-	case *map[float32]uint64:
-		*v = nil
-	case *map[float32]uintptr:
-		*v = nil
-	case *map[float32]int:
-		*v = nil
-	case *map[float32]int8:
-		*v = nil
-	case *map[float32]int16:
-		*v = nil
-	case *map[float32]int32:
-		*v = nil
-	case *map[float32]int64:
-		*v = nil
-	case *map[float32]float32:
-		*v = nil
-	case *map[float32]float64:
-		*v = nil
-	case *map[float32]bool:
-		*v = nil
+	case map[float64]interface{}:
+		fastpathTV.DecMapFloat64IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]string:
+		fastpathTV.DecMapFloat64StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]uint:
+		fastpathTV.DecMapFloat64UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]uint8:
+		fastpathTV.DecMapFloat64Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]uint16:
+		fastpathTV.DecMapFloat64Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]uint32:
+		fastpathTV.DecMapFloat64Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]uint64:
+		fastpathTV.DecMapFloat64Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]uintptr:
+		fastpathTV.DecMapFloat64UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]int:
+		fastpathTV.DecMapFloat64IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]int8:
+		fastpathTV.DecMapFloat64Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]int16:
+		fastpathTV.DecMapFloat64Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]int32:
+		fastpathTV.DecMapFloat64Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]int64:
+		fastpathTV.DecMapFloat64Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]float32:
+		fastpathTV.DecMapFloat64Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]float64:
+		fastpathTV.DecMapFloat64Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[float64]bool:
+		fastpathTV.DecMapFloat64BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[float64]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapFloat64BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []uint:
+		fastpathTV.DecSliceUintV(v, fastpathCheckNilFalse, false, d)
+	case *[]uint:
+		v2, changed2 := fastpathTV.DecSliceUintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]interface{}:
+		fastpathTV.DecMapUintIntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintIntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]string:
+		fastpathTV.DecMapUintStringV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintStringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]uint:
+		fastpathTV.DecMapUintUintV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintUintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]uint8:
+		fastpathTV.DecMapUintUint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintUint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]uint16:
+		fastpathTV.DecMapUintUint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintUint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]uint32:
+		fastpathTV.DecMapUintUint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintUint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]uint64:
+		fastpathTV.DecMapUintUint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintUint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]uintptr:
+		fastpathTV.DecMapUintUintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintUintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]int:
+		fastpathTV.DecMapUintIntV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintIntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]int8:
+		fastpathTV.DecMapUintInt8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintInt8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]int16:
+		fastpathTV.DecMapUintInt16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintInt16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]int32:
+		fastpathTV.DecMapUintInt32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintInt32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]int64:
+		fastpathTV.DecMapUintInt64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintInt64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]float32:
+		fastpathTV.DecMapUintFloat32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintFloat32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]float64:
+		fastpathTV.DecMapUintFloat64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintFloat64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint]bool:
+		fastpathTV.DecMapUintBoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintBoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]interface{}:
+		fastpathTV.DecMapUint8IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]string:
+		fastpathTV.DecMapUint8StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]uint:
+		fastpathTV.DecMapUint8UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]uint8:
+		fastpathTV.DecMapUint8Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]uint16:
+		fastpathTV.DecMapUint8Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]uint32:
+		fastpathTV.DecMapUint8Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]uint64:
+		fastpathTV.DecMapUint8Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]uintptr:
+		fastpathTV.DecMapUint8UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]int:
+		fastpathTV.DecMapUint8IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]int8:
+		fastpathTV.DecMapUint8Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]int16:
+		fastpathTV.DecMapUint8Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]int32:
+		fastpathTV.DecMapUint8Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]int64:
+		fastpathTV.DecMapUint8Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]float32:
+		fastpathTV.DecMapUint8Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]float64:
+		fastpathTV.DecMapUint8Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint8]bool:
+		fastpathTV.DecMapUint8BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint8]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint8BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []uint16:
+		fastpathTV.DecSliceUint16V(v, fastpathCheckNilFalse, false, d)
+	case *[]uint16:
+		v2, changed2 := fastpathTV.DecSliceUint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]interface{}:
+		fastpathTV.DecMapUint16IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]string:
+		fastpathTV.DecMapUint16StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]uint:
+		fastpathTV.DecMapUint16UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]uint8:
+		fastpathTV.DecMapUint16Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]uint16:
+		fastpathTV.DecMapUint16Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]uint32:
+		fastpathTV.DecMapUint16Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]uint64:
+		fastpathTV.DecMapUint16Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]uintptr:
+		fastpathTV.DecMapUint16UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]int:
+		fastpathTV.DecMapUint16IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]int8:
+		fastpathTV.DecMapUint16Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]int16:
+		fastpathTV.DecMapUint16Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]int32:
+		fastpathTV.DecMapUint16Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]int64:
+		fastpathTV.DecMapUint16Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]float32:
+		fastpathTV.DecMapUint16Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]float64:
+		fastpathTV.DecMapUint16Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint16]bool:
+		fastpathTV.DecMapUint16BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint16]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint16BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []uint32:
+		fastpathTV.DecSliceUint32V(v, fastpathCheckNilFalse, false, d)
+	case *[]uint32:
+		v2, changed2 := fastpathTV.DecSliceUint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]interface{}:
+		fastpathTV.DecMapUint32IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]string:
+		fastpathTV.DecMapUint32StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]uint:
+		fastpathTV.DecMapUint32UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]uint8:
+		fastpathTV.DecMapUint32Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]uint16:
+		fastpathTV.DecMapUint32Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]uint32:
+		fastpathTV.DecMapUint32Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]uint64:
+		fastpathTV.DecMapUint32Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]uintptr:
+		fastpathTV.DecMapUint32UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]int:
+		fastpathTV.DecMapUint32IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]int8:
+		fastpathTV.DecMapUint32Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]int16:
+		fastpathTV.DecMapUint32Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]int32:
+		fastpathTV.DecMapUint32Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]int64:
+		fastpathTV.DecMapUint32Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]float32:
+		fastpathTV.DecMapUint32Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]float64:
+		fastpathTV.DecMapUint32Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint32]bool:
+		fastpathTV.DecMapUint32BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint32]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint32BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []uint64:
+		fastpathTV.DecSliceUint64V(v, fastpathCheckNilFalse, false, d)
+	case *[]uint64:
+		v2, changed2 := fastpathTV.DecSliceUint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]interface{}:
+		fastpathTV.DecMapUint64IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]string:
+		fastpathTV.DecMapUint64StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]uint:
+		fastpathTV.DecMapUint64UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]uint8:
+		fastpathTV.DecMapUint64Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]uint16:
+		fastpathTV.DecMapUint64Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]uint32:
+		fastpathTV.DecMapUint64Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]uint64:
+		fastpathTV.DecMapUint64Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]uintptr:
+		fastpathTV.DecMapUint64UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]int:
+		fastpathTV.DecMapUint64IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]int8:
+		fastpathTV.DecMapUint64Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]int16:
+		fastpathTV.DecMapUint64Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]int32:
+		fastpathTV.DecMapUint64Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]int64:
+		fastpathTV.DecMapUint64Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]float32:
+		fastpathTV.DecMapUint64Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]float64:
+		fastpathTV.DecMapUint64Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uint64]bool:
+		fastpathTV.DecMapUint64BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[uint64]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUint64BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []uintptr:
+		fastpathTV.DecSliceUintptrV(v, fastpathCheckNilFalse, false, d)
+	case *[]uintptr:
+		v2, changed2 := fastpathTV.DecSliceUintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]interface{}:
+		fastpathTV.DecMapUintptrIntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrIntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]string:
+		fastpathTV.DecMapUintptrStringV(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrStringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]uint:
+		fastpathTV.DecMapUintptrUintV(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrUintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]uint8:
+		fastpathTV.DecMapUintptrUint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrUint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]uint16:
+		fastpathTV.DecMapUintptrUint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrUint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]uint32:
+		fastpathTV.DecMapUintptrUint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrUint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]uint64:
+		fastpathTV.DecMapUintptrUint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrUint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]uintptr:
+		fastpathTV.DecMapUintptrUintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrUintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]int:
+		fastpathTV.DecMapUintptrIntV(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrIntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]int8:
+		fastpathTV.DecMapUintptrInt8V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrInt8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]int16:
+		fastpathTV.DecMapUintptrInt16V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrInt16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]int32:
+		fastpathTV.DecMapUintptrInt32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrInt32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]int64:
+		fastpathTV.DecMapUintptrInt64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrInt64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]float32:
+		fastpathTV.DecMapUintptrFloat32V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrFloat32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]float64:
+		fastpathTV.DecMapUintptrFloat64V(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrFloat64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[uintptr]bool:
+		fastpathTV.DecMapUintptrBoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[uintptr]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapUintptrBoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []int:
+		fastpathTV.DecSliceIntV(v, fastpathCheckNilFalse, false, d)
+	case *[]int:
+		v2, changed2 := fastpathTV.DecSliceIntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]interface{}:
+		fastpathTV.DecMapIntIntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[int]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntIntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]string:
+		fastpathTV.DecMapIntStringV(v, fastpathCheckNilFalse, false, d)
 	case *map[int]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntStringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]uint:
+		fastpathTV.DecMapIntUintV(v, fastpathCheckNilFalse, false, d)
 	case *map[int]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntUintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]uint8:
+		fastpathTV.DecMapIntUint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntUint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]uint16:
+		fastpathTV.DecMapIntUint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntUint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]uint32:
+		fastpathTV.DecMapIntUint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntUint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]uint64:
+		fastpathTV.DecMapIntUint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntUint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]uintptr:
+		fastpathTV.DecMapIntUintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[int]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntUintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]int:
+		fastpathTV.DecMapIntIntV(v, fastpathCheckNilFalse, false, d)
 	case *map[int]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntIntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]int8:
+		fastpathTV.DecMapIntInt8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntInt8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]int16:
+		fastpathTV.DecMapIntInt16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntInt16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]int32:
+		fastpathTV.DecMapIntInt32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntInt32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]int64:
+		fastpathTV.DecMapIntInt64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntInt64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]float32:
+		fastpathTV.DecMapIntFloat32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntFloat32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]float64:
+		fastpathTV.DecMapIntFloat64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntFloat64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int]bool:
+		fastpathTV.DecMapIntBoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[int]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapIntBoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []int8:
+		fastpathTV.DecSliceInt8V(v, fastpathCheckNilFalse, false, d)
+	case *[]int8:
+		v2, changed2 := fastpathTV.DecSliceInt8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]interface{}:
+		fastpathTV.DecMapInt8IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]string:
+		fastpathTV.DecMapInt8StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]uint:
+		fastpathTV.DecMapInt8UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]uint8:
+		fastpathTV.DecMapInt8Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]uint16:
+		fastpathTV.DecMapInt8Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]uint32:
+		fastpathTV.DecMapInt8Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]uint64:
+		fastpathTV.DecMapInt8Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]uintptr:
+		fastpathTV.DecMapInt8UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]int:
+		fastpathTV.DecMapInt8IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]int8:
+		fastpathTV.DecMapInt8Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]int16:
+		fastpathTV.DecMapInt8Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]int32:
+		fastpathTV.DecMapInt8Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]int64:
+		fastpathTV.DecMapInt8Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]float32:
+		fastpathTV.DecMapInt8Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]float64:
+		fastpathTV.DecMapInt8Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int8]bool:
+		fastpathTV.DecMapInt8BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[int8]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt8BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []int16:
+		fastpathTV.DecSliceInt16V(v, fastpathCheckNilFalse, false, d)
+	case *[]int16:
+		v2, changed2 := fastpathTV.DecSliceInt16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]interface{}:
+		fastpathTV.DecMapInt16IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]string:
+		fastpathTV.DecMapInt16StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]uint:
+		fastpathTV.DecMapInt16UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]uint8:
+		fastpathTV.DecMapInt16Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]uint16:
+		fastpathTV.DecMapInt16Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]uint32:
+		fastpathTV.DecMapInt16Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]uint64:
+		fastpathTV.DecMapInt16Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]uintptr:
+		fastpathTV.DecMapInt16UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]int:
+		fastpathTV.DecMapInt16IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]int8:
+		fastpathTV.DecMapInt16Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]int16:
+		fastpathTV.DecMapInt16Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]int32:
+		fastpathTV.DecMapInt16Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]int64:
+		fastpathTV.DecMapInt16Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]float32:
+		fastpathTV.DecMapInt16Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]float64:
+		fastpathTV.DecMapInt16Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int16]bool:
+		fastpathTV.DecMapInt16BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[int16]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt16BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []int32:
+		fastpathTV.DecSliceInt32V(v, fastpathCheckNilFalse, false, d)
+	case *[]int32:
+		v2, changed2 := fastpathTV.DecSliceInt32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]interface{}:
+		fastpathTV.DecMapInt32IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]string:
+		fastpathTV.DecMapInt32StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]uint:
+		fastpathTV.DecMapInt32UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]uint8:
+		fastpathTV.DecMapInt32Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]uint16:
+		fastpathTV.DecMapInt32Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]uint32:
+		fastpathTV.DecMapInt32Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]uint64:
+		fastpathTV.DecMapInt32Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]uintptr:
+		fastpathTV.DecMapInt32UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]int:
+		fastpathTV.DecMapInt32IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]int8:
+		fastpathTV.DecMapInt32Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]int16:
+		fastpathTV.DecMapInt32Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]int32:
+		fastpathTV.DecMapInt32Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]int64:
+		fastpathTV.DecMapInt32Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]float32:
+		fastpathTV.DecMapInt32Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]float64:
+		fastpathTV.DecMapInt32Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int32]bool:
+		fastpathTV.DecMapInt32BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[int32]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt32BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []int64:
+		fastpathTV.DecSliceInt64V(v, fastpathCheckNilFalse, false, d)
+	case *[]int64:
+		v2, changed2 := fastpathTV.DecSliceInt64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]interface{}:
+		fastpathTV.DecMapInt64IntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64IntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]string:
+		fastpathTV.DecMapInt64StringV(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64StringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]uint:
+		fastpathTV.DecMapInt64UintV(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64UintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]uint8:
+		fastpathTV.DecMapInt64Uint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Uint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]uint16:
+		fastpathTV.DecMapInt64Uint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Uint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]uint32:
+		fastpathTV.DecMapInt64Uint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Uint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]uint64:
+		fastpathTV.DecMapInt64Uint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Uint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]uintptr:
+		fastpathTV.DecMapInt64UintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64UintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]int:
+		fastpathTV.DecMapInt64IntV(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64IntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]int8:
+		fastpathTV.DecMapInt64Int8V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Int8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]int16:
+		fastpathTV.DecMapInt64Int16V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Int16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]int32:
+		fastpathTV.DecMapInt64Int32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Int32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]int64:
+		fastpathTV.DecMapInt64Int64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Int64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]float32:
+		fastpathTV.DecMapInt64Float32V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Float32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]float64:
+		fastpathTV.DecMapInt64Float64V(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64Float64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[int64]bool:
+		fastpathTV.DecMapInt64BoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[int64]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapInt64BoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case []bool:
+		fastpathTV.DecSliceBoolV(v, fastpathCheckNilFalse, false, d)
+	case *[]bool:
+		v2, changed2 := fastpathTV.DecSliceBoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]interface{}:
+		fastpathTV.DecMapBoolIntfV(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]interface{}:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolIntfV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]string:
+		fastpathTV.DecMapBoolStringV(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]string:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolStringV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]uint:
+		fastpathTV.DecMapBoolUintV(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]uint:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolUintV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]uint8:
+		fastpathTV.DecMapBoolUint8V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]uint8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolUint8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]uint16:
+		fastpathTV.DecMapBoolUint16V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]uint16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolUint16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]uint32:
+		fastpathTV.DecMapBoolUint32V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]uint32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolUint32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]uint64:
+		fastpathTV.DecMapBoolUint64V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]uint64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolUint64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]uintptr:
+		fastpathTV.DecMapBoolUintptrV(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]uintptr:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolUintptrV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]int:
+		fastpathTV.DecMapBoolIntV(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]int:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolIntV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]int8:
+		fastpathTV.DecMapBoolInt8V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]int8:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolInt8V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]int16:
+		fastpathTV.DecMapBoolInt16V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]int16:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolInt16V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]int32:
+		fastpathTV.DecMapBoolInt32V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]int32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolInt32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]int64:
+		fastpathTV.DecMapBoolInt64V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]int64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolInt64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]float32:
+		fastpathTV.DecMapBoolFloat32V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]float32:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolFloat32V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]float64:
+		fastpathTV.DecMapBoolFloat64V(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]float64:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolFloat64V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
+	case map[bool]bool:
+		fastpathTV.DecMapBoolBoolV(v, fastpathCheckNilFalse, false, d)
 	case *map[bool]bool:
-		*v = nil
+		v2, changed2 := fastpathTV.DecMapBoolBoolV(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2
+		}
+
 	default:
-		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
 		return false
 	}
 	return true
@@ -17721,29 +18123,36 @@ func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
 
 // -- -- fast path functions
 
-func (d *Decoder) fastpathDecSliceIntfR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]interface{})
-		v, changed := fastpathTV.DecSliceIntfV(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceIntfR(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]interface{})
+		v, changed := fastpathTV.DecSliceIntfV(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]interface{})
-		v2, changed := fastpathTV.DecSliceIntfV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]interface{})
+		fastpathTV.DecSliceIntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceIntfX(vp *[]interface{}, d *Decoder) {
-	v, changed := f.DecSliceIntfV(*vp, true, d)
+
+func (f fastpathT) DecSliceIntfX(vp *[]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceIntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceIntfV(v []interface{}, canChange bool, d *Decoder) (_ []interface{}, changed bool) {
+func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, d *Decoder) (_ []interface{}, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -17757,89 +18166,127 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, canChange bool, d *Decoder) (_
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]interface{}, xlen)
+					}
+				} else {
+					v = make([]interface{}, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]interface{}, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			d.decode(&v[j])
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, nil)
+				slh.ElemContainerState(j)
+				d.decode(&v[j])
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]interface{}, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, nil)
+				if v == nil {
+					v = []interface{}{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = nil
-		} else {
-			d.decode(&v[j])
+		if cap(v) == 0 {
+			v = make([]interface{}, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, nil)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				d.decode(&v[j])
+
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]interface{}, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceStringR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]string)
-		v, changed := fastpathTV.DecSliceStringV(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceStringR(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]string)
+		v, changed := fastpathTV.DecSliceStringV(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]string)
-		v2, changed := fastpathTV.DecSliceStringV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]string)
+		fastpathTV.DecSliceStringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceStringX(vp *[]string, d *Decoder) {
-	v, changed := f.DecSliceStringV(*vp, true, d)
+
+func (f fastpathT) DecSliceStringX(vp *[]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceStringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceStringV(v []string, canChange bool, d *Decoder) (_ []string, changed bool) {
+func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d *Decoder) (_ []string, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -17853,190 +18300,131 @@ func (_ fastpathT) DecSliceStringV(v []string, canChange bool, d *Decoder) (_ []
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]string, xlen)
+					}
+				} else {
+					v = make([]string, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]string, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			} else {
-				xlen = 8
-			}
-			v = make([]string, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
 			if canChange {
-				v = append(v, "")
+				v = v[:containerLenS]
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = ""
-		} else {
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
 			v[j] = dd.DecodeString()
 		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]string, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]float32)
-		v, changed := fastpathTV.DecSliceFloat32V(*vp, !array, d)
-		if changed {
-			*vp = v
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, "")
+				slh.ElemContainerState(j)
+				v[j] = dd.DecodeString()
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
+			}
 		}
 	} else {
-		v := rv2i(rv).([]float32)
-		v2, changed := fastpathTV.DecSliceFloat32V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceFloat32X(vp *[]float32, d *Decoder) {
-	v, changed := f.DecSliceFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceFloat32V(v []float32, canChange bool, d *Decoder) (_ []float32, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []float32{}
-			} else if len(v) != 0 {
-				v = v[:0]
+		breakFound := dd.CheckBreak()
+		if breakFound {
+			if canChange {
+				if v == nil {
+					v = []string{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
+				changed = true
 			}
-			changed = true
+			slh.End()
+			return v, changed
 		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]float32, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
+		if cap(v) == 0 {
+			v = make([]string, 1, 4)
 			changed = true
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			} else {
-				xlen = 8
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, "")
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
 			}
-			v = make([]float32, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = dd.DecodeString()
 			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
+				d.swallow()
 			}
+			breakFound = dd.CheckBreak()
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		}
-	}
-	if canChange {
-		if j < len(v) {
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]float32, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]float64)
-		v, changed := fastpathTV.DecSliceFloat64V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceFloat32R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]float32)
+		v, changed := fastpathTV.DecSliceFloat32V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]float64)
-		v2, changed := fastpathTV.DecSliceFloat64V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]float32)
+		fastpathTV.DecSliceFloat32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceFloat64X(vp *[]float64, d *Decoder) {
-	v, changed := f.DecSliceFloat64V(*vp, true, d)
+
+func (f fastpathT) DecSliceFloat32X(vp *[]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceFloat32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceFloat64V(v []float64, canChange bool, d *Decoder) (_ []float64, changed bool) {
+func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, d *Decoder) (_ []float32, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
 			if v == nil {
-				v = []float64{}
+				v = []float32{}
 			} else if len(v) != 0 {
 				v = v[:0]
 			}
@@ -18045,94 +18433,131 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, canChange bool, d *Decoder) (_
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]float32, xlen)
+					}
+				} else {
+					v = make([]float32, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]float64, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = float32(dd.DecodeFloat(true))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = float32(dd.DecodeFloat(true))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]float64, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []float32{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = dd.DecodeFloat64()
+		if cap(v) == 0 {
+			v = make([]float32, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = float32(dd.DecodeFloat(true))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]float64, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceUintR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint)
-		v, changed := fastpathTV.DecSliceUintV(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceFloat64R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]float64)
+		v, changed := fastpathTV.DecSliceFloat64V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]uint)
-		v2, changed := fastpathTV.DecSliceUintV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]float64)
+		fastpathTV.DecSliceFloat64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceUintX(vp *[]uint, d *Decoder) {
-	v, changed := f.DecSliceUintV(*vp, true, d)
+
+func (f fastpathT) DecSliceFloat64X(vp *[]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceFloat64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
-}
-func (_ fastpathT) DecSliceUintV(v []uint, canChange bool, d *Decoder) (_ []uint, changed bool) {
-	dd := d.d
+}
+func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, d *Decoder) (_ []float64, changed bool) {
+	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
 			if v == nil {
-				v = []uint{}
+				v = []float64{}
 			} else if len(v) != 0 {
 				v = v[:0]
 			}
@@ -18141,94 +18566,131 @@ func (_ fastpathT) DecSliceUintV(v []uint, canChange bool, d *Decoder) (_ []uint
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]float64, xlen)
+					}
+				} else {
+					v = make([]float64, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]uint, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = dd.DecodeFloat(false)
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = dd.DecodeFloat(false)
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]uint, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []float64{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if cap(v) == 0 {
+			v = make([]float64, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = dd.DecodeFloat(false)
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceUint8R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint8)
-		v, changed := fastpathTV.DecSliceUint8V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceUintR(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]uint)
+		v, changed := fastpathTV.DecSliceUintV(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]uint8)
-		v2, changed := fastpathTV.DecSliceUint8V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]uint)
+		fastpathTV.DecSliceUintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceUint8X(vp *[]uint8, d *Decoder) {
-	v, changed := f.DecSliceUint8V(*vp, true, d)
+
+func (f fastpathT) DecSliceUintX(vp *[]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceUintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
+func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Decoder) (_ []uint, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
 			if v == nil {
-				v = []uint8{}
+				v = []uint{}
 			} else if len(v) != 0 {
 				v = v[:0]
 			}
@@ -18237,89 +18699,126 @@ func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []ui
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]uint, xlen)
+					}
+				} else {
+					v = make([]uint, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]uint8, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = uint(dd.DecodeUint(uintBitsize))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = uint(dd.DecodeUint(uintBitsize))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]uint8, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []uint{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if cap(v) == 0 {
+			v = make([]uint, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = uint(dd.DecodeUint(uintBitsize))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint8, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceUint16R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint16)
-		v, changed := fastpathTV.DecSliceUint16V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceUint16R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]uint16)
+		v, changed := fastpathTV.DecSliceUint16V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]uint16)
-		v2, changed := fastpathTV.DecSliceUint16V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]uint16)
+		fastpathTV.DecSliceUint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceUint16X(vp *[]uint16, d *Decoder) {
-	v, changed := f.DecSliceUint16V(*vp, true, d)
+
+func (f fastpathT) DecSliceUint16X(vp *[]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceUint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceUint16V(v []uint16, canChange bool, d *Decoder) (_ []uint16, changed bool) {
+func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d *Decoder) (_ []uint16, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -18333,89 +18832,126 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, canChange bool, d *Decoder) (_ []
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]uint16, xlen)
+					}
+				} else {
+					v = make([]uint16, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]uint16, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = uint16(dd.DecodeUint(16))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = uint16(dd.DecodeUint(16))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]uint16, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []uint16{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if cap(v) == 0 {
+			v = make([]uint16, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = uint16(dd.DecodeUint(16))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint16, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceUint32R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint32)
-		v, changed := fastpathTV.DecSliceUint32V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceUint32R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]uint32)
+		v, changed := fastpathTV.DecSliceUint32V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]uint32)
-		v2, changed := fastpathTV.DecSliceUint32V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]uint32)
+		fastpathTV.DecSliceUint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceUint32X(vp *[]uint32, d *Decoder) {
-	v, changed := f.DecSliceUint32V(*vp, true, d)
+
+func (f fastpathT) DecSliceUint32X(vp *[]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceUint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceUint32V(v []uint32, canChange bool, d *Decoder) (_ []uint32, changed bool) {
+func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d *Decoder) (_ []uint32, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -18429,89 +18965,126 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, canChange bool, d *Decoder) (_ []
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]uint32, xlen)
+					}
+				} else {
+					v = make([]uint32, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]uint32, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = uint32(dd.DecodeUint(32))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = uint32(dd.DecodeUint(32))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]uint32, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []uint32{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if cap(v) == 0 {
+			v = make([]uint32, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = uint32(dd.DecodeUint(32))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint32, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceUint64R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint64)
-		v, changed := fastpathTV.DecSliceUint64V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceUint64R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]uint64)
+		v, changed := fastpathTV.DecSliceUint64V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]uint64)
-		v2, changed := fastpathTV.DecSliceUint64V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]uint64)
+		fastpathTV.DecSliceUint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceUint64X(vp *[]uint64, d *Decoder) {
-	v, changed := f.DecSliceUint64V(*vp, true, d)
+
+func (f fastpathT) DecSliceUint64X(vp *[]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceUint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceUint64V(v []uint64, canChange bool, d *Decoder) (_ []uint64, changed bool) {
+func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d *Decoder) (_ []uint64, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -18525,89 +19098,126 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, canChange bool, d *Decoder) (_ []
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]uint64, xlen)
+					}
+				} else {
+					v = make([]uint64, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]uint64, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = dd.DecodeUint(64)
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = dd.DecodeUint(64)
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]uint64, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []uint64{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = dd.DecodeUint64()
+		if cap(v) == 0 {
+			v = make([]uint64, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = dd.DecodeUint(64)
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint64, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uintptr)
-		v, changed := fastpathTV.DecSliceUintptrV(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceUintptrR(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]uintptr)
+		v, changed := fastpathTV.DecSliceUintptrV(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]uintptr)
-		v2, changed := fastpathTV.DecSliceUintptrV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]uintptr)
+		fastpathTV.DecSliceUintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceUintptrX(vp *[]uintptr, d *Decoder) {
-	v, changed := f.DecSliceUintptrV(*vp, true, d)
+
+func (f fastpathT) DecSliceUintptrX(vp *[]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceUintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceUintptrV(v []uintptr, canChange bool, d *Decoder) (_ []uintptr, changed bool) {
+func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool, d *Decoder) (_ []uintptr, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -18621,89 +19231,126 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, canChange bool, d *Decoder) (_
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]uintptr, xlen)
+					}
+				} else {
+					v = make([]uintptr, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]uintptr, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = uintptr(dd.DecodeUint(uintBitsize))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = uintptr(dd.DecodeUint(uintBitsize))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]uintptr, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []uintptr{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if cap(v) == 0 {
+			v = make([]uintptr, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = uintptr(dd.DecodeUint(uintBitsize))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uintptr, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceIntR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int)
-		v, changed := fastpathTV.DecSliceIntV(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceIntR(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]int)
+		v, changed := fastpathTV.DecSliceIntV(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]int)
-		v2, changed := fastpathTV.DecSliceIntV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]int)
+		fastpathTV.DecSliceIntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceIntX(vp *[]int, d *Decoder) {
-	v, changed := f.DecSliceIntV(*vp, true, d)
+
+func (f fastpathT) DecSliceIntX(vp *[]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceIntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceIntV(v []int, canChange bool, d *Decoder) (_ []int, changed bool) {
+func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decoder) (_ []int, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -18717,89 +19364,126 @@ func (_ fastpathT) DecSliceIntV(v []int, canChange bool, d *Decoder) (_ []int, c
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]int, xlen)
+					}
+				} else {
+					v = make([]int, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]int, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = int(dd.DecodeInt(intBitsize))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = int(dd.DecodeInt(intBitsize))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]int, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []int{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if cap(v) == 0 {
+			v = make([]int, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = int(dd.DecodeInt(intBitsize))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceInt8R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int8)
-		v, changed := fastpathTV.DecSliceInt8V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceInt8R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]int8)
+		v, changed := fastpathTV.DecSliceInt8V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]int8)
-		v2, changed := fastpathTV.DecSliceInt8V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]int8)
+		fastpathTV.DecSliceInt8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceInt8X(vp *[]int8, d *Decoder) {
-	v, changed := f.DecSliceInt8V(*vp, true, d)
+
+func (f fastpathT) DecSliceInt8X(vp *[]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceInt8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceInt8V(v []int8, canChange bool, d *Decoder) (_ []int8, changed bool) {
+func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Decoder) (_ []int8, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -18813,89 +19497,126 @@ func (_ fastpathT) DecSliceInt8V(v []int8, canChange bool, d *Decoder) (_ []int8
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]int8, xlen)
+					}
+				} else {
+					v = make([]int8, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]int8, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = int8(dd.DecodeInt(8))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = int8(dd.DecodeInt(8))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
+			}
+		}
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
+			if canChange {
+				if v == nil {
+					v = []int8{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
+				changed = true
 			}
-			v = make([]int8, xlen)
+			slh.End()
+			return v, changed
+		}
+		if cap(v) == 0 {
+			v = make([]int8, 1, 4)
 			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = int8(dd.DecodeInt(8))
 			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
+				d.swallow()
 			}
+			breakFound = dd.CheckBreak()
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		}
-	}
-	if canChange {
-		if j < len(v) {
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int8, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceInt16R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int16)
-		v, changed := fastpathTV.DecSliceInt16V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceInt16R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]int16)
+		v, changed := fastpathTV.DecSliceInt16V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]int16)
-		v2, changed := fastpathTV.DecSliceInt16V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]int16)
+		fastpathTV.DecSliceInt16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceInt16X(vp *[]int16, d *Decoder) {
-	v, changed := f.DecSliceInt16V(*vp, true, d)
+
+func (f fastpathT) DecSliceInt16X(vp *[]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceInt16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceInt16V(v []int16, canChange bool, d *Decoder) (_ []int16, changed bool) {
+func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *Decoder) (_ []int16, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -18909,89 +19630,126 @@ func (_ fastpathT) DecSliceInt16V(v []int16, canChange bool, d *Decoder) (_ []in
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]int16, xlen)
+					}
+				} else {
+					v = make([]int16, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]int16, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = int16(dd.DecodeInt(16))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = int16(dd.DecodeInt(16))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]int16, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []int16{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if cap(v) == 0 {
+			v = make([]int16, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = int16(dd.DecodeInt(16))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int16, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceInt32R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int32)
-		v, changed := fastpathTV.DecSliceInt32V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceInt32R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]int32)
+		v, changed := fastpathTV.DecSliceInt32V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]int32)
-		v2, changed := fastpathTV.DecSliceInt32V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]int32)
+		fastpathTV.DecSliceInt32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceInt32X(vp *[]int32, d *Decoder) {
-	v, changed := f.DecSliceInt32V(*vp, true, d)
+
+func (f fastpathT) DecSliceInt32X(vp *[]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceInt32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceInt32V(v []int32, canChange bool, d *Decoder) (_ []int32, changed bool) {
+func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *Decoder) (_ []int32, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -19005,89 +19763,126 @@ func (_ fastpathT) DecSliceInt32V(v []int32, canChange bool, d *Decoder) (_ []in
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]int32, xlen)
+					}
+				} else {
+					v = make([]int32, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]int32, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = int32(dd.DecodeInt(32))
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = int32(dd.DecodeInt(32))
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]int32, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []int32{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if cap(v) == 0 {
+			v = make([]int32, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = int32(dd.DecodeInt(32))
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int32, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceInt64R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int64)
-		v, changed := fastpathTV.DecSliceInt64V(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceInt64R(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]int64)
+		v, changed := fastpathTV.DecSliceInt64V(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]int64)
-		v2, changed := fastpathTV.DecSliceInt64V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]int64)
+		fastpathTV.DecSliceInt64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceInt64X(vp *[]int64, d *Decoder) {
-	v, changed := f.DecSliceInt64V(*vp, true, d)
+
+func (f fastpathT) DecSliceInt64X(vp *[]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceInt64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceInt64V(v []int64, canChange bool, d *Decoder) (_ []int64, changed bool) {
+func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *Decoder) (_ []int64, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -19101,89 +19896,126 @@ func (_ fastpathT) DecSliceInt64V(v []int64, canChange bool, d *Decoder) (_ []in
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]int64, xlen)
+					}
+				} else {
+					v = make([]int64, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]int64, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = dd.DecodeInt(64)
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, 0)
+				slh.ElemContainerState(j)
+				v[j] = dd.DecodeInt(64)
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]int64, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, 0)
+				if v == nil {
+					v = []int64{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = dd.DecodeInt64()
+		if cap(v) == 0 {
+			v = make([]int64, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, 0)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = dd.DecodeInt(64)
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int64, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecSliceBoolR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]bool)
-		v, changed := fastpathTV.DecSliceBoolV(*vp, !array, d)
+func (f *decFnInfo) fastpathDecSliceBoolR(rv reflect.Value) {
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() {
+		vp := rv.Addr().Interface().(*[]bool)
+		v, changed := fastpathTV.DecSliceBoolV(*vp, fastpathCheckNilFalse, !array, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		v := rv2i(rv).([]bool)
-		v2, changed := fastpathTV.DecSliceBoolV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
+		v := rv.Interface().([]bool)
+		fastpathTV.DecSliceBoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecSliceBoolX(vp *[]bool, d *Decoder) {
-	v, changed := f.DecSliceBoolV(*vp, true, d)
+
+func (f fastpathT) DecSliceBoolX(vp *[]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecSliceBoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecSliceBoolV(v []bool, canChange bool, d *Decoder) (_ []bool, changed bool) {
+func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Decoder) (_ []bool, changed bool) {
 	dd := d.d
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	slh, containerLenS := d.decSliceHelperStart()
 	if containerLenS == 0 {
 		if canChange {
@@ -19197,15326 +20029,19324 @@ func (_ fastpathT) DecSliceBoolV(v []bool, canChange bool, d *Decoder) (_ []bool
 		slh.End()
 		return v, changed
 	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
+
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool
 		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			if xlen <= cap(v) {
-				v = v[:xlen]
+			if canChange {
+				var xlen int
+				xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]bool, xlen)
+					}
+				} else {
+					v = make([]bool, xlen)
+				}
+				changed = true
 			} else {
-				v = make([]bool, xlen)
+				d.arrayCannotExpand(len(v), containerLenS)
 			}
-			changed = true
+			x2read = len(v)
 		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
 		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			} else {
-				xlen = 8
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			v[j] = dd.DecodeBool()
+		}
+		if xtrunc {
+			for ; j < containerLenS; j++ {
+				v = append(v, false)
+				slh.ElemContainerState(j)
+				v[j] = dd.DecodeBool()
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
 			}
-			v = make([]bool, xlen)
-			changed = true
 		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
+	} else {
+		breakFound := dd.CheckBreak()
+		if breakFound {
 			if canChange {
-				v = append(v, false)
+				if v == nil {
+					v = []bool{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
 				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
 			}
+			slh.End()
+			return v, changed
 		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = false
-		} else {
-			v[j] = dd.DecodeBool()
+		if cap(v) == 0 {
+			v = make([]bool, 1, 4)
+			changed = true
 		}
-	}
-	if canChange {
-		if j < len(v) {
+		j := 0
+		for ; !breakFound; j++ {
+			if j >= len(v) {
+				if canChange {
+					v = append(v, false)
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) {
+				v[j] = dd.DecodeBool()
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
 			v = v[:j]
 			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]bool, 0)
-			changed = true
 		}
 	}
 	slh.End()
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]interface{})
-		v, changed := fastpathTV.DecMapIntfIntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfIntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]interface{})
+		v, changed := fastpathTV.DecMapIntfIntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfIntfV(rv2i(rv).(map[interface{}]interface{}), false, d)
+		v := rv.Interface().(map[interface{}]interface{})
+		fastpathTV.DecMapIntfIntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfIntfX(vp *map[interface{}]interface{}, d *Decoder) {
-	v, changed := f.DecMapIntfIntfV(*vp, true, d)
+func (f fastpathT) DecMapIntfIntfX(vp *map[interface{}]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfIntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, canChange bool,
+func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32)
 		v = make(map[interface{}]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk interface{}
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]string)
-		v, changed := fastpathTV.DecMapIntfStringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfStringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]string)
+		v, changed := fastpathTV.DecMapIntfStringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfStringV(rv2i(rv).(map[interface{}]string), false, d)
+		v := rv.Interface().(map[interface{}]string)
+		fastpathTV.DecMapIntfStringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfStringX(vp *map[interface{}]string, d *Decoder) {
-	v, changed := f.DecMapIntfStringV(*vp, true, d)
+func (f fastpathT) DecMapIntfStringX(vp *map[interface{}]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfStringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, canChange bool,
+func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32)
 		v = make(map[interface{}]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint)
-		v, changed := fastpathTV.DecMapIntfUintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfUintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]uint)
+		v, changed := fastpathTV.DecMapIntfUintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfUintV(rv2i(rv).(map[interface{}]uint), false, d)
+		v := rv.Interface().(map[interface{}]uint)
+		fastpathTV.DecMapIntfUintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfUintX(vp *map[interface{}]uint, d *Decoder) {
-	v, changed := f.DecMapIntfUintV(*vp, true, d)
+func (f fastpathT) DecMapIntfUintX(vp *map[interface{}]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfUintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, canChange bool,
+func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[interface{}]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint8)
-		v, changed := fastpathTV.DecMapIntfUint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfUint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]uint8)
+		v, changed := fastpathTV.DecMapIntfUint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfUint8V(rv2i(rv).(map[interface{}]uint8), false, d)
+		v := rv.Interface().(map[interface{}]uint8)
+		fastpathTV.DecMapIntfUint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfUint8X(vp *map[interface{}]uint8, d *Decoder) {
-	v, changed := f.DecMapIntfUint8V(*vp, true, d)
+func (f fastpathT) DecMapIntfUint8X(vp *map[interface{}]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfUint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, canChange bool,
+func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[interface{}]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint16)
-		v, changed := fastpathTV.DecMapIntfUint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfUint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]uint16)
+		v, changed := fastpathTV.DecMapIntfUint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfUint16V(rv2i(rv).(map[interface{}]uint16), false, d)
+		v := rv.Interface().(map[interface{}]uint16)
+		fastpathTV.DecMapIntfUint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfUint16X(vp *map[interface{}]uint16, d *Decoder) {
-	v, changed := f.DecMapIntfUint16V(*vp, true, d)
+func (f fastpathT) DecMapIntfUint16X(vp *map[interface{}]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfUint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, canChange bool,
+func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[interface{}]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint32)
-		v, changed := fastpathTV.DecMapIntfUint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfUint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]uint32)
+		v, changed := fastpathTV.DecMapIntfUint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfUint32V(rv2i(rv).(map[interface{}]uint32), false, d)
+		v := rv.Interface().(map[interface{}]uint32)
+		fastpathTV.DecMapIntfUint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfUint32X(vp *map[interface{}]uint32, d *Decoder) {
-	v, changed := f.DecMapIntfUint32V(*vp, true, d)
+func (f fastpathT) DecMapIntfUint32X(vp *map[interface{}]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfUint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, canChange bool,
+func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[interface{}]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint64)
-		v, changed := fastpathTV.DecMapIntfUint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfUint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]uint64)
+		v, changed := fastpathTV.DecMapIntfUint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfUint64V(rv2i(rv).(map[interface{}]uint64), false, d)
+		v := rv.Interface().(map[interface{}]uint64)
+		fastpathTV.DecMapIntfUint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfUint64X(vp *map[interface{}]uint64, d *Decoder) {
-	v, changed := f.DecMapIntfUint64V(*vp, true, d)
+func (f fastpathT) DecMapIntfUint64X(vp *map[interface{}]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfUint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, canChange bool,
+func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[interface{}]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uintptr)
-		v, changed := fastpathTV.DecMapIntfUintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfUintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]uintptr)
+		v, changed := fastpathTV.DecMapIntfUintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfUintptrV(rv2i(rv).(map[interface{}]uintptr), false, d)
+		v := rv.Interface().(map[interface{}]uintptr)
+		fastpathTV.DecMapIntfUintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfUintptrX(vp *map[interface{}]uintptr, d *Decoder) {
-	v, changed := f.DecMapIntfUintptrV(*vp, true, d)
+func (f fastpathT) DecMapIntfUintptrX(vp *map[interface{}]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfUintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfUintptrV(v map[interface{}]uintptr, canChange bool,
+func (_ fastpathT) DecMapIntfUintptrV(v map[interface{}]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[interface{}]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int)
-		v, changed := fastpathTV.DecMapIntfIntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfIntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]int)
+		v, changed := fastpathTV.DecMapIntfIntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfIntV(rv2i(rv).(map[interface{}]int), false, d)
+		v := rv.Interface().(map[interface{}]int)
+		fastpathTV.DecMapIntfIntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfIntX(vp *map[interface{}]int, d *Decoder) {
-	v, changed := f.DecMapIntfIntV(*vp, true, d)
+func (f fastpathT) DecMapIntfIntX(vp *map[interface{}]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfIntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, canChange bool,
+func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[interface{}]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int8)
-		v, changed := fastpathTV.DecMapIntfInt8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfInt8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]int8)
+		v, changed := fastpathTV.DecMapIntfInt8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfInt8V(rv2i(rv).(map[interface{}]int8), false, d)
+		v := rv.Interface().(map[interface{}]int8)
+		fastpathTV.DecMapIntfInt8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfInt8X(vp *map[interface{}]int8, d *Decoder) {
-	v, changed := f.DecMapIntfInt8V(*vp, true, d)
+func (f fastpathT) DecMapIntfInt8X(vp *map[interface{}]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfInt8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, canChange bool,
+func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[interface{}]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int16)
-		v, changed := fastpathTV.DecMapIntfInt16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfInt16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]int16)
+		v, changed := fastpathTV.DecMapIntfInt16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfInt16V(rv2i(rv).(map[interface{}]int16), false, d)
+		v := rv.Interface().(map[interface{}]int16)
+		fastpathTV.DecMapIntfInt16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfInt16X(vp *map[interface{}]int16, d *Decoder) {
-	v, changed := f.DecMapIntfInt16V(*vp, true, d)
+func (f fastpathT) DecMapIntfInt16X(vp *map[interface{}]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfInt16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, canChange bool,
+func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[interface{}]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int32)
-		v, changed := fastpathTV.DecMapIntfInt32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfInt32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]int32)
+		v, changed := fastpathTV.DecMapIntfInt32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfInt32V(rv2i(rv).(map[interface{}]int32), false, d)
+		v := rv.Interface().(map[interface{}]int32)
+		fastpathTV.DecMapIntfInt32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfInt32X(vp *map[interface{}]int32, d *Decoder) {
-	v, changed := f.DecMapIntfInt32V(*vp, true, d)
+func (f fastpathT) DecMapIntfInt32X(vp *map[interface{}]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfInt32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, canChange bool,
+func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[interface{}]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int64)
-		v, changed := fastpathTV.DecMapIntfInt64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfInt64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]int64)
+		v, changed := fastpathTV.DecMapIntfInt64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfInt64V(rv2i(rv).(map[interface{}]int64), false, d)
+		v := rv.Interface().(map[interface{}]int64)
+		fastpathTV.DecMapIntfInt64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfInt64X(vp *map[interface{}]int64, d *Decoder) {
-	v, changed := f.DecMapIntfInt64V(*vp, true, d)
+func (f fastpathT) DecMapIntfInt64X(vp *map[interface{}]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfInt64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, canChange bool,
+func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[interface{}]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]float32)
-		v, changed := fastpathTV.DecMapIntfFloat32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfFloat32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]float32)
+		v, changed := fastpathTV.DecMapIntfFloat32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfFloat32V(rv2i(rv).(map[interface{}]float32), false, d)
+		v := rv.Interface().(map[interface{}]float32)
+		fastpathTV.DecMapIntfFloat32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfFloat32X(vp *map[interface{}]float32, d *Decoder) {
-	v, changed := f.DecMapIntfFloat32V(*vp, true, d)
+func (f fastpathT) DecMapIntfFloat32X(vp *map[interface{}]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfFloat32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, canChange bool,
+func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[interface{}]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]float64)
-		v, changed := fastpathTV.DecMapIntfFloat64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfFloat64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]float64)
+		v, changed := fastpathTV.DecMapIntfFloat64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfFloat64V(rv2i(rv).(map[interface{}]float64), false, d)
+		v := rv.Interface().(map[interface{}]float64)
+		fastpathTV.DecMapIntfFloat64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfFloat64X(vp *map[interface{}]float64, d *Decoder) {
-	v, changed := f.DecMapIntfFloat64V(*vp, true, d)
+func (f fastpathT) DecMapIntfFloat64X(vp *map[interface{}]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfFloat64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, canChange bool,
+func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[interface{}]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntfBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]bool)
-		v, changed := fastpathTV.DecMapIntfBoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntfBoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[interface{}]bool)
+		v, changed := fastpathTV.DecMapIntfBoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntfBoolV(rv2i(rv).(map[interface{}]bool), false, d)
+		v := rv.Interface().(map[interface{}]bool)
+		fastpathTV.DecMapIntfBoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntfBoolX(vp *map[interface{}]bool, d *Decoder) {
-	v, changed := f.DecMapIntfBoolV(*vp, true, d)
+func (f fastpathT) DecMapIntfBoolX(vp *map[interface{}]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntfBoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, canChange bool,
+func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[interface{}]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[interface{}]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk interface{}
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = nil
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv)
+			}
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]interface{})
-		v, changed := fastpathTV.DecMapStringIntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringIntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]interface{})
+		v, changed := fastpathTV.DecMapStringIntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringIntfV(rv2i(rv).(map[string]interface{}), false, d)
+		v := rv.Interface().(map[string]interface{})
+		fastpathTV.DecMapStringIntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringIntfX(vp *map[string]interface{}, d *Decoder) {
-	v, changed := f.DecMapStringIntfV(*vp, true, d)
+func (f fastpathT) DecMapStringIntfX(vp *map[string]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringIntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, canChange bool,
+func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32)
 		v = make(map[string]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk string
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]string)
-		v, changed := fastpathTV.DecMapStringStringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringStringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]string)
+		v, changed := fastpathTV.DecMapStringStringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringStringV(rv2i(rv).(map[string]string), false, d)
+		v := rv.Interface().(map[string]string)
+		fastpathTV.DecMapStringStringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringStringX(vp *map[string]string, d *Decoder) {
-	v, changed := f.DecMapStringStringV(*vp, true, d)
+func (f fastpathT) DecMapStringStringX(vp *map[string]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringStringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringStringV(v map[string]string, canChange bool,
+func (_ fastpathT) DecMapStringStringV(v map[string]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32)
 		v = make(map[string]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint)
-		v, changed := fastpathTV.DecMapStringUintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringUintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]uint)
+		v, changed := fastpathTV.DecMapStringUintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringUintV(rv2i(rv).(map[string]uint), false, d)
+		v := rv.Interface().(map[string]uint)
+		fastpathTV.DecMapStringUintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringUintX(vp *map[string]uint, d *Decoder) {
-	v, changed := f.DecMapStringUintV(*vp, true, d)
+func (f fastpathT) DecMapStringUintX(vp *map[string]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringUintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringUintV(v map[string]uint, canChange bool,
+func (_ fastpathT) DecMapStringUintV(v map[string]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[string]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint8)
-		v, changed := fastpathTV.DecMapStringUint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringUint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]uint8)
+		v, changed := fastpathTV.DecMapStringUint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringUint8V(rv2i(rv).(map[string]uint8), false, d)
+		v := rv.Interface().(map[string]uint8)
+		fastpathTV.DecMapStringUint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringUint8X(vp *map[string]uint8, d *Decoder) {
-	v, changed := f.DecMapStringUint8V(*vp, true, d)
+func (f fastpathT) DecMapStringUint8X(vp *map[string]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringUint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, canChange bool,
+func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[string]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint16)
-		v, changed := fastpathTV.DecMapStringUint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringUint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]uint16)
+		v, changed := fastpathTV.DecMapStringUint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringUint16V(rv2i(rv).(map[string]uint16), false, d)
+		v := rv.Interface().(map[string]uint16)
+		fastpathTV.DecMapStringUint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringUint16X(vp *map[string]uint16, d *Decoder) {
-	v, changed := f.DecMapStringUint16V(*vp, true, d)
+func (f fastpathT) DecMapStringUint16X(vp *map[string]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringUint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, canChange bool,
+func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[string]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint32)
-		v, changed := fastpathTV.DecMapStringUint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringUint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]uint32)
+		v, changed := fastpathTV.DecMapStringUint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringUint32V(rv2i(rv).(map[string]uint32), false, d)
+		v := rv.Interface().(map[string]uint32)
+		fastpathTV.DecMapStringUint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringUint32X(vp *map[string]uint32, d *Decoder) {
-	v, changed := f.DecMapStringUint32V(*vp, true, d)
+func (f fastpathT) DecMapStringUint32X(vp *map[string]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringUint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, canChange bool,
+func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[string]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint64)
-		v, changed := fastpathTV.DecMapStringUint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringUint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]uint64)
+		v, changed := fastpathTV.DecMapStringUint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringUint64V(rv2i(rv).(map[string]uint64), false, d)
+		v := rv.Interface().(map[string]uint64)
+		fastpathTV.DecMapStringUint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringUint64X(vp *map[string]uint64, d *Decoder) {
-	v, changed := f.DecMapStringUint64V(*vp, true, d)
+func (f fastpathT) DecMapStringUint64X(vp *map[string]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringUint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, canChange bool,
+func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[string]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uintptr)
-		v, changed := fastpathTV.DecMapStringUintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringUintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]uintptr)
+		v, changed := fastpathTV.DecMapStringUintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringUintptrV(rv2i(rv).(map[string]uintptr), false, d)
+		v := rv.Interface().(map[string]uintptr)
+		fastpathTV.DecMapStringUintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringUintptrX(vp *map[string]uintptr, d *Decoder) {
-	v, changed := f.DecMapStringUintptrV(*vp, true, d)
+func (f fastpathT) DecMapStringUintptrX(vp *map[string]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringUintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringUintptrV(v map[string]uintptr, canChange bool,
+func (_ fastpathT) DecMapStringUintptrV(v map[string]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[string]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int)
-		v, changed := fastpathTV.DecMapStringIntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringIntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]int)
+		v, changed := fastpathTV.DecMapStringIntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringIntV(rv2i(rv).(map[string]int), false, d)
+		v := rv.Interface().(map[string]int)
+		fastpathTV.DecMapStringIntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringIntX(vp *map[string]int, d *Decoder) {
-	v, changed := f.DecMapStringIntV(*vp, true, d)
+func (f fastpathT) DecMapStringIntX(vp *map[string]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringIntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringIntV(v map[string]int, canChange bool,
+func (_ fastpathT) DecMapStringIntV(v map[string]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[string]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int8)
-		v, changed := fastpathTV.DecMapStringInt8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringInt8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]int8)
+		v, changed := fastpathTV.DecMapStringInt8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringInt8V(rv2i(rv).(map[string]int8), false, d)
+		v := rv.Interface().(map[string]int8)
+		fastpathTV.DecMapStringInt8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringInt8X(vp *map[string]int8, d *Decoder) {
-	v, changed := f.DecMapStringInt8V(*vp, true, d)
+func (f fastpathT) DecMapStringInt8X(vp *map[string]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringInt8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringInt8V(v map[string]int8, canChange bool,
+func (_ fastpathT) DecMapStringInt8V(v map[string]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[string]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int16)
-		v, changed := fastpathTV.DecMapStringInt16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringInt16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]int16)
+		v, changed := fastpathTV.DecMapStringInt16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringInt16V(rv2i(rv).(map[string]int16), false, d)
+		v := rv.Interface().(map[string]int16)
+		fastpathTV.DecMapStringInt16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringInt16X(vp *map[string]int16, d *Decoder) {
-	v, changed := f.DecMapStringInt16V(*vp, true, d)
+func (f fastpathT) DecMapStringInt16X(vp *map[string]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringInt16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringInt16V(v map[string]int16, canChange bool,
+func (_ fastpathT) DecMapStringInt16V(v map[string]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[string]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int32)
-		v, changed := fastpathTV.DecMapStringInt32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringInt32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]int32)
+		v, changed := fastpathTV.DecMapStringInt32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringInt32V(rv2i(rv).(map[string]int32), false, d)
+		v := rv.Interface().(map[string]int32)
+		fastpathTV.DecMapStringInt32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringInt32X(vp *map[string]int32, d *Decoder) {
-	v, changed := f.DecMapStringInt32V(*vp, true, d)
+func (f fastpathT) DecMapStringInt32X(vp *map[string]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringInt32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringInt32V(v map[string]int32, canChange bool,
+func (_ fastpathT) DecMapStringInt32V(v map[string]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[string]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int64)
-		v, changed := fastpathTV.DecMapStringInt64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringInt64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]int64)
+		v, changed := fastpathTV.DecMapStringInt64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringInt64V(rv2i(rv).(map[string]int64), false, d)
+		v := rv.Interface().(map[string]int64)
+		fastpathTV.DecMapStringInt64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringInt64X(vp *map[string]int64, d *Decoder) {
-	v, changed := f.DecMapStringInt64V(*vp, true, d)
+func (f fastpathT) DecMapStringInt64X(vp *map[string]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringInt64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringInt64V(v map[string]int64, canChange bool,
+func (_ fastpathT) DecMapStringInt64V(v map[string]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[string]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]float32)
-		v, changed := fastpathTV.DecMapStringFloat32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringFloat32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]float32)
+		v, changed := fastpathTV.DecMapStringFloat32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringFloat32V(rv2i(rv).(map[string]float32), false, d)
+		v := rv.Interface().(map[string]float32)
+		fastpathTV.DecMapStringFloat32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringFloat32X(vp *map[string]float32, d *Decoder) {
-	v, changed := f.DecMapStringFloat32V(*vp, true, d)
+func (f fastpathT) DecMapStringFloat32X(vp *map[string]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringFloat32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, canChange bool,
+func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[string]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]float64)
-		v, changed := fastpathTV.DecMapStringFloat64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringFloat64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]float64)
+		v, changed := fastpathTV.DecMapStringFloat64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringFloat64V(rv2i(rv).(map[string]float64), false, d)
+		v := rv.Interface().(map[string]float64)
+		fastpathTV.DecMapStringFloat64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringFloat64X(vp *map[string]float64, d *Decoder) {
-	v, changed := f.DecMapStringFloat64V(*vp, true, d)
+func (f fastpathT) DecMapStringFloat64X(vp *map[string]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringFloat64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, canChange bool,
+func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[string]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapStringBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]bool)
-		v, changed := fastpathTV.DecMapStringBoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapStringBoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[string]bool)
+		v, changed := fastpathTV.DecMapStringBoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapStringBoolV(rv2i(rv).(map[string]bool), false, d)
+		v := rv.Interface().(map[string]bool)
+		fastpathTV.DecMapStringBoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapStringBoolX(vp *map[string]bool, d *Decoder) {
-	v, changed := f.DecMapStringBoolV(*vp, true, d)
+func (f fastpathT) DecMapStringBoolX(vp *map[string]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapStringBoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapStringBoolV(v map[string]bool, canChange bool,
+func (_ fastpathT) DecMapStringBoolV(v map[string]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[string]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[string]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk string
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeString()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]interface{})
-		v, changed := fastpathTV.DecMapFloat32IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]interface{})
+		v, changed := fastpathTV.DecMapFloat32IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32IntfV(rv2i(rv).(map[float32]interface{}), false, d)
+		v := rv.Interface().(map[float32]interface{})
+		fastpathTV.DecMapFloat32IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32IntfX(vp *map[float32]interface{}, d *Decoder) {
-	v, changed := f.DecMapFloat32IntfV(*vp, true, d)
+func (f fastpathT) DecMapFloat32IntfX(vp *map[float32]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, canChange bool,
+func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[float32]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk float32
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]string)
-		v, changed := fastpathTV.DecMapFloat32StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]string)
+		v, changed := fastpathTV.DecMapFloat32StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32StringV(rv2i(rv).(map[float32]string), false, d)
+		v := rv.Interface().(map[float32]string)
+		fastpathTV.DecMapFloat32StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32StringX(vp *map[float32]string, d *Decoder) {
-	v, changed := f.DecMapFloat32StringV(*vp, true, d)
+func (f fastpathT) DecMapFloat32StringX(vp *map[float32]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, canChange bool,
+func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[float32]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint)
-		v, changed := fastpathTV.DecMapFloat32UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]uint)
+		v, changed := fastpathTV.DecMapFloat32UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32UintV(rv2i(rv).(map[float32]uint), false, d)
+		v := rv.Interface().(map[float32]uint)
+		fastpathTV.DecMapFloat32UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32UintX(vp *map[float32]uint, d *Decoder) {
-	v, changed := f.DecMapFloat32UintV(*vp, true, d)
+func (f fastpathT) DecMapFloat32UintX(vp *map[float32]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, canChange bool,
+func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float32]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint8)
-		v, changed := fastpathTV.DecMapFloat32Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]uint8)
+		v, changed := fastpathTV.DecMapFloat32Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Uint8V(rv2i(rv).(map[float32]uint8), false, d)
+		v := rv.Interface().(map[float32]uint8)
+		fastpathTV.DecMapFloat32Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Uint8X(vp *map[float32]uint8, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint8V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Uint8X(vp *map[float32]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, canChange bool,
+func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[float32]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint16)
-		v, changed := fastpathTV.DecMapFloat32Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]uint16)
+		v, changed := fastpathTV.DecMapFloat32Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Uint16V(rv2i(rv).(map[float32]uint16), false, d)
+		v := rv.Interface().(map[float32]uint16)
+		fastpathTV.DecMapFloat32Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Uint16X(vp *map[float32]uint16, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint16V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Uint16X(vp *map[float32]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, canChange bool,
+func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[float32]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint32)
-		v, changed := fastpathTV.DecMapFloat32Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]uint32)
+		v, changed := fastpathTV.DecMapFloat32Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Uint32V(rv2i(rv).(map[float32]uint32), false, d)
+		v := rv.Interface().(map[float32]uint32)
+		fastpathTV.DecMapFloat32Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Uint32X(vp *map[float32]uint32, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint32V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Uint32X(vp *map[float32]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, canChange bool,
+func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[float32]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint64)
-		v, changed := fastpathTV.DecMapFloat32Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]uint64)
+		v, changed := fastpathTV.DecMapFloat32Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Uint64V(rv2i(rv).(map[float32]uint64), false, d)
+		v := rv.Interface().(map[float32]uint64)
+		fastpathTV.DecMapFloat32Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Uint64X(vp *map[float32]uint64, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint64V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Uint64X(vp *map[float32]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, canChange bool,
+func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float32]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uintptr)
-		v, changed := fastpathTV.DecMapFloat32UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]uintptr)
+		v, changed := fastpathTV.DecMapFloat32UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32UintptrV(rv2i(rv).(map[float32]uintptr), false, d)
+		v := rv.Interface().(map[float32]uintptr)
+		fastpathTV.DecMapFloat32UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32UintptrX(vp *map[float32]uintptr, d *Decoder) {
-	v, changed := f.DecMapFloat32UintptrV(*vp, true, d)
+func (f fastpathT) DecMapFloat32UintptrX(vp *map[float32]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32UintptrV(v map[float32]uintptr, canChange bool,
+func (_ fastpathT) DecMapFloat32UintptrV(v map[float32]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float32]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int)
-		v, changed := fastpathTV.DecMapFloat32IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]int)
+		v, changed := fastpathTV.DecMapFloat32IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32IntV(rv2i(rv).(map[float32]int), false, d)
+		v := rv.Interface().(map[float32]int)
+		fastpathTV.DecMapFloat32IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32IntX(vp *map[float32]int, d *Decoder) {
-	v, changed := f.DecMapFloat32IntV(*vp, true, d)
+func (f fastpathT) DecMapFloat32IntX(vp *map[float32]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, canChange bool,
+func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float32]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int8)
-		v, changed := fastpathTV.DecMapFloat32Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]int8)
+		v, changed := fastpathTV.DecMapFloat32Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Int8V(rv2i(rv).(map[float32]int8), false, d)
+		v := rv.Interface().(map[float32]int8)
+		fastpathTV.DecMapFloat32Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Int8X(vp *map[float32]int8, d *Decoder) {
-	v, changed := f.DecMapFloat32Int8V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Int8X(vp *map[float32]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, canChange bool,
+func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[float32]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int16)
-		v, changed := fastpathTV.DecMapFloat32Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]int16)
+		v, changed := fastpathTV.DecMapFloat32Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Int16V(rv2i(rv).(map[float32]int16), false, d)
+		v := rv.Interface().(map[float32]int16)
+		fastpathTV.DecMapFloat32Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Int16X(vp *map[float32]int16, d *Decoder) {
-	v, changed := f.DecMapFloat32Int16V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Int16X(vp *map[float32]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, canChange bool,
+func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[float32]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int32)
-		v, changed := fastpathTV.DecMapFloat32Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]int32)
+		v, changed := fastpathTV.DecMapFloat32Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Int32V(rv2i(rv).(map[float32]int32), false, d)
+		v := rv.Interface().(map[float32]int32)
+		fastpathTV.DecMapFloat32Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Int32X(vp *map[float32]int32, d *Decoder) {
-	v, changed := f.DecMapFloat32Int32V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Int32X(vp *map[float32]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, canChange bool,
+func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[float32]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int64)
-		v, changed := fastpathTV.DecMapFloat32Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]int64)
+		v, changed := fastpathTV.DecMapFloat32Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Int64V(rv2i(rv).(map[float32]int64), false, d)
+		v := rv.Interface().(map[float32]int64)
+		fastpathTV.DecMapFloat32Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Int64X(vp *map[float32]int64, d *Decoder) {
-	v, changed := f.DecMapFloat32Int64V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Int64X(vp *map[float32]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, canChange bool,
+func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float32]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]float32)
-		v, changed := fastpathTV.DecMapFloat32Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]float32)
+		v, changed := fastpathTV.DecMapFloat32Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Float32V(rv2i(rv).(map[float32]float32), false, d)
+		v := rv.Interface().(map[float32]float32)
+		fastpathTV.DecMapFloat32Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Float32X(vp *map[float32]float32, d *Decoder) {
-	v, changed := f.DecMapFloat32Float32V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Float32X(vp *map[float32]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, canChange bool,
+func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[float32]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]float64)
-		v, changed := fastpathTV.DecMapFloat32Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]float64)
+		v, changed := fastpathTV.DecMapFloat32Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32Float64V(rv2i(rv).(map[float32]float64), false, d)
+		v := rv.Interface().(map[float32]float64)
+		fastpathTV.DecMapFloat32Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32Float64X(vp *map[float32]float64, d *Decoder) {
-	v, changed := f.DecMapFloat32Float64V(*vp, true, d)
+func (f fastpathT) DecMapFloat32Float64X(vp *map[float32]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, canChange bool,
+func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float32]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat32BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]bool)
-		v, changed := fastpathTV.DecMapFloat32BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat32BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float32]bool)
+		v, changed := fastpathTV.DecMapFloat32BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat32BoolV(rv2i(rv).(map[float32]bool), false, d)
+		v := rv.Interface().(map[float32]bool)
+		fastpathTV.DecMapFloat32BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat32BoolX(vp *map[float32]bool, d *Decoder) {
-	v, changed := f.DecMapFloat32BoolV(*vp, true, d)
+func (f fastpathT) DecMapFloat32BoolX(vp *map[float32]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat32BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, canChange bool,
+func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float32]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[float32]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float32
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = float32(dd.DecodeFloat(true))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]interface{})
-		v, changed := fastpathTV.DecMapFloat64IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]interface{})
+		v, changed := fastpathTV.DecMapFloat64IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64IntfV(rv2i(rv).(map[float64]interface{}), false, d)
+		v := rv.Interface().(map[float64]interface{})
+		fastpathTV.DecMapFloat64IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64IntfX(vp *map[float64]interface{}, d *Decoder) {
-	v, changed := f.DecMapFloat64IntfV(*vp, true, d)
+func (f fastpathT) DecMapFloat64IntfX(vp *map[float64]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, canChange bool,
+func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[float64]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk float64
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]string)
-		v, changed := fastpathTV.DecMapFloat64StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]string)
+		v, changed := fastpathTV.DecMapFloat64StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64StringV(rv2i(rv).(map[float64]string), false, d)
+		v := rv.Interface().(map[float64]string)
+		fastpathTV.DecMapFloat64StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64StringX(vp *map[float64]string, d *Decoder) {
-	v, changed := f.DecMapFloat64StringV(*vp, true, d)
+func (f fastpathT) DecMapFloat64StringX(vp *map[float64]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, canChange bool,
+func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[float64]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint)
-		v, changed := fastpathTV.DecMapFloat64UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]uint)
+		v, changed := fastpathTV.DecMapFloat64UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64UintV(rv2i(rv).(map[float64]uint), false, d)
+		v := rv.Interface().(map[float64]uint)
+		fastpathTV.DecMapFloat64UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64UintX(vp *map[float64]uint, d *Decoder) {
-	v, changed := f.DecMapFloat64UintV(*vp, true, d)
+func (f fastpathT) DecMapFloat64UintX(vp *map[float64]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, canChange bool,
+func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[float64]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint8)
-		v, changed := fastpathTV.DecMapFloat64Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]uint8)
+		v, changed := fastpathTV.DecMapFloat64Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Uint8V(rv2i(rv).(map[float64]uint8), false, d)
+		v := rv.Interface().(map[float64]uint8)
+		fastpathTV.DecMapFloat64Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Uint8X(vp *map[float64]uint8, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint8V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Uint8X(vp *map[float64]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
-}
-func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, canChange bool,
-	d *Decoder) (_ map[float64]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+}
+func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, checkNil bool, canChange bool,
+	d *Decoder) (_ map[float64]uint8, changed bool) {
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[float64]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint16)
-		v, changed := fastpathTV.DecMapFloat64Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]uint16)
+		v, changed := fastpathTV.DecMapFloat64Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Uint16V(rv2i(rv).(map[float64]uint16), false, d)
+		v := rv.Interface().(map[float64]uint16)
+		fastpathTV.DecMapFloat64Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Uint16X(vp *map[float64]uint16, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint16V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Uint16X(vp *map[float64]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, canChange bool,
+func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[float64]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint32)
-		v, changed := fastpathTV.DecMapFloat64Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]uint32)
+		v, changed := fastpathTV.DecMapFloat64Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Uint32V(rv2i(rv).(map[float64]uint32), false, d)
+		v := rv.Interface().(map[float64]uint32)
+		fastpathTV.DecMapFloat64Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Uint32X(vp *map[float64]uint32, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint32V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Uint32X(vp *map[float64]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, canChange bool,
+func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float64]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint64)
-		v, changed := fastpathTV.DecMapFloat64Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]uint64)
+		v, changed := fastpathTV.DecMapFloat64Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Uint64V(rv2i(rv).(map[float64]uint64), false, d)
+		v := rv.Interface().(map[float64]uint64)
+		fastpathTV.DecMapFloat64Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Uint64X(vp *map[float64]uint64, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint64V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Uint64X(vp *map[float64]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, canChange bool,
+func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[float64]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uintptr)
-		v, changed := fastpathTV.DecMapFloat64UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]uintptr)
+		v, changed := fastpathTV.DecMapFloat64UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64UintptrV(rv2i(rv).(map[float64]uintptr), false, d)
+		v := rv.Interface().(map[float64]uintptr)
+		fastpathTV.DecMapFloat64UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64UintptrX(vp *map[float64]uintptr, d *Decoder) {
-	v, changed := f.DecMapFloat64UintptrV(*vp, true, d)
+func (f fastpathT) DecMapFloat64UintptrX(vp *map[float64]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64UintptrV(v map[float64]uintptr, canChange bool,
+func (_ fastpathT) DecMapFloat64UintptrV(v map[float64]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[float64]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int)
-		v, changed := fastpathTV.DecMapFloat64IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]int)
+		v, changed := fastpathTV.DecMapFloat64IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64IntV(rv2i(rv).(map[float64]int), false, d)
+		v := rv.Interface().(map[float64]int)
+		fastpathTV.DecMapFloat64IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64IntX(vp *map[float64]int, d *Decoder) {
-	v, changed := f.DecMapFloat64IntV(*vp, true, d)
+func (f fastpathT) DecMapFloat64IntX(vp *map[float64]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, canChange bool,
+func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[float64]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int8)
-		v, changed := fastpathTV.DecMapFloat64Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]int8)
+		v, changed := fastpathTV.DecMapFloat64Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Int8V(rv2i(rv).(map[float64]int8), false, d)
+		v := rv.Interface().(map[float64]int8)
+		fastpathTV.DecMapFloat64Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Int8X(vp *map[float64]int8, d *Decoder) {
-	v, changed := f.DecMapFloat64Int8V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Int8X(vp *map[float64]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, canChange bool,
+func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[float64]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int16)
-		v, changed := fastpathTV.DecMapFloat64Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]int16)
+		v, changed := fastpathTV.DecMapFloat64Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Int16V(rv2i(rv).(map[float64]int16), false, d)
+		v := rv.Interface().(map[float64]int16)
+		fastpathTV.DecMapFloat64Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Int16X(vp *map[float64]int16, d *Decoder) {
-	v, changed := f.DecMapFloat64Int16V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Int16X(vp *map[float64]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, canChange bool,
+func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[float64]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int32)
-		v, changed := fastpathTV.DecMapFloat64Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]int32)
+		v, changed := fastpathTV.DecMapFloat64Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Int32V(rv2i(rv).(map[float64]int32), false, d)
+		v := rv.Interface().(map[float64]int32)
+		fastpathTV.DecMapFloat64Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Int32X(vp *map[float64]int32, d *Decoder) {
-	v, changed := f.DecMapFloat64Int32V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Int32X(vp *map[float64]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, canChange bool,
+func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float64]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int64)
-		v, changed := fastpathTV.DecMapFloat64Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]int64)
+		v, changed := fastpathTV.DecMapFloat64Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Int64V(rv2i(rv).(map[float64]int64), false, d)
+		v := rv.Interface().(map[float64]int64)
+		fastpathTV.DecMapFloat64Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Int64X(vp *map[float64]int64, d *Decoder) {
-	v, changed := f.DecMapFloat64Int64V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Int64X(vp *map[float64]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, canChange bool,
+func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[float64]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]float32)
-		v, changed := fastpathTV.DecMapFloat64Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]float32)
+		v, changed := fastpathTV.DecMapFloat64Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Float32V(rv2i(rv).(map[float64]float32), false, d)
+		v := rv.Interface().(map[float64]float32)
+		fastpathTV.DecMapFloat64Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Float32X(vp *map[float64]float32, d *Decoder) {
-	v, changed := f.DecMapFloat64Float32V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Float32X(vp *map[float64]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, canChange bool,
+func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[float64]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]float64)
-		v, changed := fastpathTV.DecMapFloat64Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]float64)
+		v, changed := fastpathTV.DecMapFloat64Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64Float64V(rv2i(rv).(map[float64]float64), false, d)
+		v := rv.Interface().(map[float64]float64)
+		fastpathTV.DecMapFloat64Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64Float64X(vp *map[float64]float64, d *Decoder) {
-	v, changed := f.DecMapFloat64Float64V(*vp, true, d)
+func (f fastpathT) DecMapFloat64Float64X(vp *map[float64]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, canChange bool,
+func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[float64]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapFloat64BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]bool)
-		v, changed := fastpathTV.DecMapFloat64BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapFloat64BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[float64]bool)
+		v, changed := fastpathTV.DecMapFloat64BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapFloat64BoolV(rv2i(rv).(map[float64]bool), false, d)
+		v := rv.Interface().(map[float64]bool)
+		fastpathTV.DecMapFloat64BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapFloat64BoolX(vp *map[float64]bool, d *Decoder) {
-	v, changed := f.DecMapFloat64BoolV(*vp, true, d)
+func (f fastpathT) DecMapFloat64BoolX(vp *map[float64]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapFloat64BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, canChange bool,
+func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[float64]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[float64]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk float64
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeFloat(false)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]interface{})
-		v, changed := fastpathTV.DecMapUintIntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintIntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]interface{})
+		v, changed := fastpathTV.DecMapUintIntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintIntfV(rv2i(rv).(map[uint]interface{}), false, d)
+		v := rv.Interface().(map[uint]interface{})
+		fastpathTV.DecMapUintIntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintIntfX(vp *map[uint]interface{}, d *Decoder) {
-	v, changed := f.DecMapUintIntfV(*vp, true, d)
+func (f fastpathT) DecMapUintIntfX(vp *map[uint]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintIntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, canChange bool,
+func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[uint]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk uint
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]string)
-		v, changed := fastpathTV.DecMapUintStringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintStringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]string)
+		v, changed := fastpathTV.DecMapUintStringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintStringV(rv2i(rv).(map[uint]string), false, d)
+		v := rv.Interface().(map[uint]string)
+		fastpathTV.DecMapUintStringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintStringX(vp *map[uint]string, d *Decoder) {
-	v, changed := f.DecMapUintStringV(*vp, true, d)
+func (f fastpathT) DecMapUintStringX(vp *map[uint]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintStringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintStringV(v map[uint]string, canChange bool,
+func (_ fastpathT) DecMapUintStringV(v map[uint]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[uint]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint)
-		v, changed := fastpathTV.DecMapUintUintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintUintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]uint)
+		v, changed := fastpathTV.DecMapUintUintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintUintV(rv2i(rv).(map[uint]uint), false, d)
+		v := rv.Interface().(map[uint]uint)
+		fastpathTV.DecMapUintUintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintUintX(vp *map[uint]uint, d *Decoder) {
-	v, changed := f.DecMapUintUintV(*vp, true, d)
+func (f fastpathT) DecMapUintUintX(vp *map[uint]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintUintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintUintV(v map[uint]uint, canChange bool,
+func (_ fastpathT) DecMapUintUintV(v map[uint]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint8)
-		v, changed := fastpathTV.DecMapUintUint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintUint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]uint8)
+		v, changed := fastpathTV.DecMapUintUint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintUint8V(rv2i(rv).(map[uint]uint8), false, d)
+		v := rv.Interface().(map[uint]uint8)
+		fastpathTV.DecMapUintUint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintUint8X(vp *map[uint]uint8, d *Decoder) {
-	v, changed := f.DecMapUintUint8V(*vp, true, d)
+func (f fastpathT) DecMapUintUint8X(vp *map[uint]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintUint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, canChange bool,
+func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint16)
-		v, changed := fastpathTV.DecMapUintUint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintUint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]uint16)
+		v, changed := fastpathTV.DecMapUintUint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintUint16V(rv2i(rv).(map[uint]uint16), false, d)
+		v := rv.Interface().(map[uint]uint16)
+		fastpathTV.DecMapUintUint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintUint16X(vp *map[uint]uint16, d *Decoder) {
-	v, changed := f.DecMapUintUint16V(*vp, true, d)
+func (f fastpathT) DecMapUintUint16X(vp *map[uint]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintUint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, canChange bool,
+func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint32)
-		v, changed := fastpathTV.DecMapUintUint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintUint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]uint32)
+		v, changed := fastpathTV.DecMapUintUint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintUint32V(rv2i(rv).(map[uint]uint32), false, d)
+		v := rv.Interface().(map[uint]uint32)
+		fastpathTV.DecMapUintUint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintUint32X(vp *map[uint]uint32, d *Decoder) {
-	v, changed := f.DecMapUintUint32V(*vp, true, d)
+func (f fastpathT) DecMapUintUint32X(vp *map[uint]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintUint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, canChange bool,
+func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint64)
-		v, changed := fastpathTV.DecMapUintUint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintUint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]uint64)
+		v, changed := fastpathTV.DecMapUintUint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintUint64V(rv2i(rv).(map[uint]uint64), false, d)
+		v := rv.Interface().(map[uint]uint64)
+		fastpathTV.DecMapUintUint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintUint64X(vp *map[uint]uint64, d *Decoder) {
-	v, changed := f.DecMapUintUint64V(*vp, true, d)
+func (f fastpathT) DecMapUintUint64X(vp *map[uint]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintUint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, canChange bool,
+func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uintptr)
-		v, changed := fastpathTV.DecMapUintUintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintUintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]uintptr)
+		v, changed := fastpathTV.DecMapUintUintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintUintptrV(rv2i(rv).(map[uint]uintptr), false, d)
+		v := rv.Interface().(map[uint]uintptr)
+		fastpathTV.DecMapUintUintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintUintptrX(vp *map[uint]uintptr, d *Decoder) {
-	v, changed := f.DecMapUintUintptrV(*vp, true, d)
+func (f fastpathT) DecMapUintUintptrX(vp *map[uint]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintUintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintUintptrV(v map[uint]uintptr, canChange bool,
+func (_ fastpathT) DecMapUintUintptrV(v map[uint]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int)
-		v, changed := fastpathTV.DecMapUintIntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintIntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]int)
+		v, changed := fastpathTV.DecMapUintIntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintIntV(rv2i(rv).(map[uint]int), false, d)
+		v := rv.Interface().(map[uint]int)
+		fastpathTV.DecMapUintIntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintIntX(vp *map[uint]int, d *Decoder) {
-	v, changed := f.DecMapUintIntV(*vp, true, d)
+func (f fastpathT) DecMapUintIntX(vp *map[uint]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintIntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintIntV(v map[uint]int, canChange bool,
+func (_ fastpathT) DecMapUintIntV(v map[uint]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int8)
-		v, changed := fastpathTV.DecMapUintInt8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintInt8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]int8)
+		v, changed := fastpathTV.DecMapUintInt8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintInt8V(rv2i(rv).(map[uint]int8), false, d)
+		v := rv.Interface().(map[uint]int8)
+		fastpathTV.DecMapUintInt8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintInt8X(vp *map[uint]int8, d *Decoder) {
-	v, changed := f.DecMapUintInt8V(*vp, true, d)
+func (f fastpathT) DecMapUintInt8X(vp *map[uint]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintInt8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, canChange bool,
+func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int16)
-		v, changed := fastpathTV.DecMapUintInt16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintInt16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]int16)
+		v, changed := fastpathTV.DecMapUintInt16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintInt16V(rv2i(rv).(map[uint]int16), false, d)
+		v := rv.Interface().(map[uint]int16)
+		fastpathTV.DecMapUintInt16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintInt16X(vp *map[uint]int16, d *Decoder) {
-	v, changed := f.DecMapUintInt16V(*vp, true, d)
+func (f fastpathT) DecMapUintInt16X(vp *map[uint]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintInt16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, canChange bool,
+func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int32)
-		v, changed := fastpathTV.DecMapUintInt32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintInt32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]int32)
+		v, changed := fastpathTV.DecMapUintInt32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintInt32V(rv2i(rv).(map[uint]int32), false, d)
+		v := rv.Interface().(map[uint]int32)
+		fastpathTV.DecMapUintInt32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintInt32X(vp *map[uint]int32, d *Decoder) {
-	v, changed := f.DecMapUintInt32V(*vp, true, d)
+func (f fastpathT) DecMapUintInt32X(vp *map[uint]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintInt32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
-}
-func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, canChange bool,
-	d *Decoder) (_ map[uint]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+}
+func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, checkNil bool, canChange bool,
+	d *Decoder) (_ map[uint]int32, changed bool) {
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int64)
-		v, changed := fastpathTV.DecMapUintInt64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintInt64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]int64)
+		v, changed := fastpathTV.DecMapUintInt64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintInt64V(rv2i(rv).(map[uint]int64), false, d)
+		v := rv.Interface().(map[uint]int64)
+		fastpathTV.DecMapUintInt64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintInt64X(vp *map[uint]int64, d *Decoder) {
-	v, changed := f.DecMapUintInt64V(*vp, true, d)
+func (f fastpathT) DecMapUintInt64X(vp *map[uint]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintInt64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, canChange bool,
+func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]float32)
-		v, changed := fastpathTV.DecMapUintFloat32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintFloat32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]float32)
+		v, changed := fastpathTV.DecMapUintFloat32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintFloat32V(rv2i(rv).(map[uint]float32), false, d)
+		v := rv.Interface().(map[uint]float32)
+		fastpathTV.DecMapUintFloat32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintFloat32X(vp *map[uint]float32, d *Decoder) {
-	v, changed := f.DecMapUintFloat32V(*vp, true, d)
+func (f fastpathT) DecMapUintFloat32X(vp *map[uint]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintFloat32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, canChange bool,
+func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]float64)
-		v, changed := fastpathTV.DecMapUintFloat64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintFloat64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]float64)
+		v, changed := fastpathTV.DecMapUintFloat64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintFloat64V(rv2i(rv).(map[uint]float64), false, d)
+		v := rv.Interface().(map[uint]float64)
+		fastpathTV.DecMapUintFloat64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintFloat64X(vp *map[uint]float64, d *Decoder) {
-	v, changed := f.DecMapUintFloat64V(*vp, true, d)
+func (f fastpathT) DecMapUintFloat64X(vp *map[uint]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintFloat64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, canChange bool,
+func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]bool)
-		v, changed := fastpathTV.DecMapUintBoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintBoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint]bool)
+		v, changed := fastpathTV.DecMapUintBoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintBoolV(rv2i(rv).(map[uint]bool), false, d)
+		v := rv.Interface().(map[uint]bool)
+		fastpathTV.DecMapUintBoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintBoolX(vp *map[uint]bool, d *Decoder) {
-	v, changed := f.DecMapUintBoolV(*vp, true, d)
+func (f fastpathT) DecMapUintBoolX(vp *map[uint]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintBoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, canChange bool,
+func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]interface{})
-		v, changed := fastpathTV.DecMapUint8IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]interface{})
+		v, changed := fastpathTV.DecMapUint8IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8IntfV(rv2i(rv).(map[uint8]interface{}), false, d)
+		v := rv.Interface().(map[uint8]interface{})
+		fastpathTV.DecMapUint8IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8IntfX(vp *map[uint8]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint8IntfV(*vp, true, d)
+func (f fastpathT) DecMapUint8IntfX(vp *map[uint8]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, canChange bool,
+func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[uint8]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk uint8
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]string)
-		v, changed := fastpathTV.DecMapUint8StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]string)
+		v, changed := fastpathTV.DecMapUint8StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8StringV(rv2i(rv).(map[uint8]string), false, d)
+		v := rv.Interface().(map[uint8]string)
+		fastpathTV.DecMapUint8StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8StringX(vp *map[uint8]string, d *Decoder) {
-	v, changed := f.DecMapUint8StringV(*vp, true, d)
+func (f fastpathT) DecMapUint8StringX(vp *map[uint8]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, canChange bool,
+func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[uint8]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint)
-		v, changed := fastpathTV.DecMapUint8UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]uint)
+		v, changed := fastpathTV.DecMapUint8UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8UintV(rv2i(rv).(map[uint8]uint), false, d)
+		v := rv.Interface().(map[uint8]uint)
+		fastpathTV.DecMapUint8UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8UintX(vp *map[uint8]uint, d *Decoder) {
-	v, changed := f.DecMapUint8UintV(*vp, true, d)
+func (f fastpathT) DecMapUint8UintX(vp *map[uint8]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, canChange bool,
+func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint8]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint8)
-		v, changed := fastpathTV.DecMapUint8Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]uint8)
+		v, changed := fastpathTV.DecMapUint8Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Uint8V(rv2i(rv).(map[uint8]uint8), false, d)
+		v := rv.Interface().(map[uint8]uint8)
+		fastpathTV.DecMapUint8Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Uint8X(vp *map[uint8]uint8, d *Decoder) {
-	v, changed := f.DecMapUint8Uint8V(*vp, true, d)
+func (f fastpathT) DecMapUint8Uint8X(vp *map[uint8]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, canChange bool,
+func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[uint8]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint16)
-		v, changed := fastpathTV.DecMapUint8Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]uint16)
+		v, changed := fastpathTV.DecMapUint8Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Uint16V(rv2i(rv).(map[uint8]uint16), false, d)
+		v := rv.Interface().(map[uint8]uint16)
+		fastpathTV.DecMapUint8Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Uint16X(vp *map[uint8]uint16, d *Decoder) {
-	v, changed := f.DecMapUint8Uint16V(*vp, true, d)
+func (f fastpathT) DecMapUint8Uint16X(vp *map[uint8]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, canChange bool,
+func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[uint8]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint32)
-		v, changed := fastpathTV.DecMapUint8Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]uint32)
+		v, changed := fastpathTV.DecMapUint8Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Uint32V(rv2i(rv).(map[uint8]uint32), false, d)
+		v := rv.Interface().(map[uint8]uint32)
+		fastpathTV.DecMapUint8Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Uint32X(vp *map[uint8]uint32, d *Decoder) {
-	v, changed := f.DecMapUint8Uint32V(*vp, true, d)
+func (f fastpathT) DecMapUint8Uint32X(vp *map[uint8]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, canChange bool,
+func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[uint8]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint64)
-		v, changed := fastpathTV.DecMapUint8Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]uint64)
+		v, changed := fastpathTV.DecMapUint8Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Uint64V(rv2i(rv).(map[uint8]uint64), false, d)
+		v := rv.Interface().(map[uint8]uint64)
+		fastpathTV.DecMapUint8Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Uint64X(vp *map[uint8]uint64, d *Decoder) {
-	v, changed := f.DecMapUint8Uint64V(*vp, true, d)
+func (f fastpathT) DecMapUint8Uint64X(vp *map[uint8]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, canChange bool,
+func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint8]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uintptr)
-		v, changed := fastpathTV.DecMapUint8UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]uintptr)
+		v, changed := fastpathTV.DecMapUint8UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8UintptrV(rv2i(rv).(map[uint8]uintptr), false, d)
+		v := rv.Interface().(map[uint8]uintptr)
+		fastpathTV.DecMapUint8UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8UintptrX(vp *map[uint8]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint8UintptrV(*vp, true, d)
+func (f fastpathT) DecMapUint8UintptrX(vp *map[uint8]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8UintptrV(v map[uint8]uintptr, canChange bool,
+func (_ fastpathT) DecMapUint8UintptrV(v map[uint8]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint8]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int)
-		v, changed := fastpathTV.DecMapUint8IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]int)
+		v, changed := fastpathTV.DecMapUint8IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8IntV(rv2i(rv).(map[uint8]int), false, d)
+		v := rv.Interface().(map[uint8]int)
+		fastpathTV.DecMapUint8IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8IntX(vp *map[uint8]int, d *Decoder) {
-	v, changed := f.DecMapUint8IntV(*vp, true, d)
+func (f fastpathT) DecMapUint8IntX(vp *map[uint8]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, canChange bool,
+func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint8]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int8)
-		v, changed := fastpathTV.DecMapUint8Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]int8)
+		v, changed := fastpathTV.DecMapUint8Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Int8V(rv2i(rv).(map[uint8]int8), false, d)
+		v := rv.Interface().(map[uint8]int8)
+		fastpathTV.DecMapUint8Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Int8X(vp *map[uint8]int8, d *Decoder) {
-	v, changed := f.DecMapUint8Int8V(*vp, true, d)
+func (f fastpathT) DecMapUint8Int8X(vp *map[uint8]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, canChange bool,
+func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[uint8]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int16)
-		v, changed := fastpathTV.DecMapUint8Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]int16)
+		v, changed := fastpathTV.DecMapUint8Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Int16V(rv2i(rv).(map[uint8]int16), false, d)
+		v := rv.Interface().(map[uint8]int16)
+		fastpathTV.DecMapUint8Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Int16X(vp *map[uint8]int16, d *Decoder) {
-	v, changed := f.DecMapUint8Int16V(*vp, true, d)
+func (f fastpathT) DecMapUint8Int16X(vp *map[uint8]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, canChange bool,
+func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[uint8]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int32)
-		v, changed := fastpathTV.DecMapUint8Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]int32)
+		v, changed := fastpathTV.DecMapUint8Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Int32V(rv2i(rv).(map[uint8]int32), false, d)
+		v := rv.Interface().(map[uint8]int32)
+		fastpathTV.DecMapUint8Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Int32X(vp *map[uint8]int32, d *Decoder) {
-	v, changed := f.DecMapUint8Int32V(*vp, true, d)
+func (f fastpathT) DecMapUint8Int32X(vp *map[uint8]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, canChange bool,
+func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[uint8]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int64)
-		v, changed := fastpathTV.DecMapUint8Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]int64)
+		v, changed := fastpathTV.DecMapUint8Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Int64V(rv2i(rv).(map[uint8]int64), false, d)
+		v := rv.Interface().(map[uint8]int64)
+		fastpathTV.DecMapUint8Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Int64X(vp *map[uint8]int64, d *Decoder) {
-	v, changed := f.DecMapUint8Int64V(*vp, true, d)
+func (f fastpathT) DecMapUint8Int64X(vp *map[uint8]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, canChange bool,
+func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint8]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]float32)
-		v, changed := fastpathTV.DecMapUint8Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]float32)
+		v, changed := fastpathTV.DecMapUint8Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Float32V(rv2i(rv).(map[uint8]float32), false, d)
+		v := rv.Interface().(map[uint8]float32)
+		fastpathTV.DecMapUint8Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Float32X(vp *map[uint8]float32, d *Decoder) {
-	v, changed := f.DecMapUint8Float32V(*vp, true, d)
+func (f fastpathT) DecMapUint8Float32X(vp *map[uint8]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, canChange bool,
+func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[uint8]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]float64)
-		v, changed := fastpathTV.DecMapUint8Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]float64)
+		v, changed := fastpathTV.DecMapUint8Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8Float64V(rv2i(rv).(map[uint8]float64), false, d)
+		v := rv.Interface().(map[uint8]float64)
+		fastpathTV.DecMapUint8Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8Float64X(vp *map[uint8]float64, d *Decoder) {
-	v, changed := f.DecMapUint8Float64V(*vp, true, d)
+func (f fastpathT) DecMapUint8Float64X(vp *map[uint8]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, canChange bool,
+func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint8]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint8BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]bool)
-		v, changed := fastpathTV.DecMapUint8BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint8BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint8]bool)
+		v, changed := fastpathTV.DecMapUint8BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint8BoolV(rv2i(rv).(map[uint8]bool), false, d)
+		v := rv.Interface().(map[uint8]bool)
+		fastpathTV.DecMapUint8BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint8BoolX(vp *map[uint8]bool, d *Decoder) {
-	v, changed := f.DecMapUint8BoolV(*vp, true, d)
+func (f fastpathT) DecMapUint8BoolX(vp *map[uint8]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint8BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, canChange bool,
+func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint8]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[uint8]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint8
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint8(dd.DecodeUint(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]interface{})
-		v, changed := fastpathTV.DecMapUint16IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]interface{})
+		v, changed := fastpathTV.DecMapUint16IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16IntfV(rv2i(rv).(map[uint16]interface{}), false, d)
+		v := rv.Interface().(map[uint16]interface{})
+		fastpathTV.DecMapUint16IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16IntfX(vp *map[uint16]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint16IntfV(*vp, true, d)
+func (f fastpathT) DecMapUint16IntfX(vp *map[uint16]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, canChange bool,
+func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[uint16]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk uint16
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]string)
-		v, changed := fastpathTV.DecMapUint16StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]string)
+		v, changed := fastpathTV.DecMapUint16StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16StringV(rv2i(rv).(map[uint16]string), false, d)
+		v := rv.Interface().(map[uint16]string)
+		fastpathTV.DecMapUint16StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16StringX(vp *map[uint16]string, d *Decoder) {
-	v, changed := f.DecMapUint16StringV(*vp, true, d)
+func (f fastpathT) DecMapUint16StringX(vp *map[uint16]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, canChange bool,
+func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[uint16]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint)
-		v, changed := fastpathTV.DecMapUint16UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]uint)
+		v, changed := fastpathTV.DecMapUint16UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16UintV(rv2i(rv).(map[uint16]uint), false, d)
+		v := rv.Interface().(map[uint16]uint)
+		fastpathTV.DecMapUint16UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16UintX(vp *map[uint16]uint, d *Decoder) {
-	v, changed := f.DecMapUint16UintV(*vp, true, d)
+func (f fastpathT) DecMapUint16UintX(vp *map[uint16]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, canChange bool,
+func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint16]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint8)
-		v, changed := fastpathTV.DecMapUint16Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]uint8)
+		v, changed := fastpathTV.DecMapUint16Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Uint8V(rv2i(rv).(map[uint16]uint8), false, d)
+		v := rv.Interface().(map[uint16]uint8)
+		fastpathTV.DecMapUint16Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Uint8X(vp *map[uint16]uint8, d *Decoder) {
-	v, changed := f.DecMapUint16Uint8V(*vp, true, d)
+func (f fastpathT) DecMapUint16Uint8X(vp *map[uint16]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
-}
-func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, canChange bool,
-	d *Decoder) (_ map[uint16]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+}
+func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, checkNil bool, canChange bool,
+	d *Decoder) (_ map[uint16]uint8, changed bool) {
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[uint16]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint16)
-		v, changed := fastpathTV.DecMapUint16Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]uint16)
+		v, changed := fastpathTV.DecMapUint16Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Uint16V(rv2i(rv).(map[uint16]uint16), false, d)
+		v := rv.Interface().(map[uint16]uint16)
+		fastpathTV.DecMapUint16Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Uint16X(vp *map[uint16]uint16, d *Decoder) {
-	v, changed := f.DecMapUint16Uint16V(*vp, true, d)
+func (f fastpathT) DecMapUint16Uint16X(vp *map[uint16]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, canChange bool,
+func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4)
 		v = make(map[uint16]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint32)
-		v, changed := fastpathTV.DecMapUint16Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]uint32)
+		v, changed := fastpathTV.DecMapUint16Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Uint32V(rv2i(rv).(map[uint16]uint32), false, d)
+		v := rv.Interface().(map[uint16]uint32)
+		fastpathTV.DecMapUint16Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Uint32X(vp *map[uint16]uint32, d *Decoder) {
-	v, changed := f.DecMapUint16Uint32V(*vp, true, d)
+func (f fastpathT) DecMapUint16Uint32X(vp *map[uint16]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, canChange bool,
+func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[uint16]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint64)
-		v, changed := fastpathTV.DecMapUint16Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]uint64)
+		v, changed := fastpathTV.DecMapUint16Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Uint64V(rv2i(rv).(map[uint16]uint64), false, d)
+		v := rv.Interface().(map[uint16]uint64)
+		fastpathTV.DecMapUint16Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Uint64X(vp *map[uint16]uint64, d *Decoder) {
-	v, changed := f.DecMapUint16Uint64V(*vp, true, d)
+func (f fastpathT) DecMapUint16Uint64X(vp *map[uint16]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, canChange bool,
+func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint16]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uintptr)
-		v, changed := fastpathTV.DecMapUint16UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]uintptr)
+		v, changed := fastpathTV.DecMapUint16UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16UintptrV(rv2i(rv).(map[uint16]uintptr), false, d)
+		v := rv.Interface().(map[uint16]uintptr)
+		fastpathTV.DecMapUint16UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16UintptrX(vp *map[uint16]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint16UintptrV(*vp, true, d)
+func (f fastpathT) DecMapUint16UintptrX(vp *map[uint16]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16UintptrV(v map[uint16]uintptr, canChange bool,
+func (_ fastpathT) DecMapUint16UintptrV(v map[uint16]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint16]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int)
-		v, changed := fastpathTV.DecMapUint16IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]int)
+		v, changed := fastpathTV.DecMapUint16IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16IntV(rv2i(rv).(map[uint16]int), false, d)
+		v := rv.Interface().(map[uint16]int)
+		fastpathTV.DecMapUint16IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16IntX(vp *map[uint16]int, d *Decoder) {
-	v, changed := f.DecMapUint16IntV(*vp, true, d)
+func (f fastpathT) DecMapUint16IntX(vp *map[uint16]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, canChange bool,
+func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint16]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int8)
-		v, changed := fastpathTV.DecMapUint16Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]int8)
+		v, changed := fastpathTV.DecMapUint16Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Int8V(rv2i(rv).(map[uint16]int8), false, d)
+		v := rv.Interface().(map[uint16]int8)
+		fastpathTV.DecMapUint16Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Int8X(vp *map[uint16]int8, d *Decoder) {
-	v, changed := f.DecMapUint16Int8V(*vp, true, d)
+func (f fastpathT) DecMapUint16Int8X(vp *map[uint16]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, canChange bool,
+func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[uint16]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int16)
-		v, changed := fastpathTV.DecMapUint16Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]int16)
+		v, changed := fastpathTV.DecMapUint16Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Int16V(rv2i(rv).(map[uint16]int16), false, d)
+		v := rv.Interface().(map[uint16]int16)
+		fastpathTV.DecMapUint16Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Int16X(vp *map[uint16]int16, d *Decoder) {
-	v, changed := f.DecMapUint16Int16V(*vp, true, d)
+func (f fastpathT) DecMapUint16Int16X(vp *map[uint16]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, canChange bool,
+func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4)
 		v = make(map[uint16]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int32)
-		v, changed := fastpathTV.DecMapUint16Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]int32)
+		v, changed := fastpathTV.DecMapUint16Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Int32V(rv2i(rv).(map[uint16]int32), false, d)
+		v := rv.Interface().(map[uint16]int32)
+		fastpathTV.DecMapUint16Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Int32X(vp *map[uint16]int32, d *Decoder) {
-	v, changed := f.DecMapUint16Int32V(*vp, true, d)
+func (f fastpathT) DecMapUint16Int32X(vp *map[uint16]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, canChange bool,
+func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[uint16]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int64)
-		v, changed := fastpathTV.DecMapUint16Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]int64)
+		v, changed := fastpathTV.DecMapUint16Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Int64V(rv2i(rv).(map[uint16]int64), false, d)
+		v := rv.Interface().(map[uint16]int64)
+		fastpathTV.DecMapUint16Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Int64X(vp *map[uint16]int64, d *Decoder) {
-	v, changed := f.DecMapUint16Int64V(*vp, true, d)
+func (f fastpathT) DecMapUint16Int64X(vp *map[uint16]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, canChange bool,
+func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint16]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]float32)
-		v, changed := fastpathTV.DecMapUint16Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]float32)
+		v, changed := fastpathTV.DecMapUint16Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Float32V(rv2i(rv).(map[uint16]float32), false, d)
+		v := rv.Interface().(map[uint16]float32)
+		fastpathTV.DecMapUint16Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Float32X(vp *map[uint16]float32, d *Decoder) {
-	v, changed := f.DecMapUint16Float32V(*vp, true, d)
+func (f fastpathT) DecMapUint16Float32X(vp *map[uint16]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, canChange bool,
+func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[uint16]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]float64)
-		v, changed := fastpathTV.DecMapUint16Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]float64)
+		v, changed := fastpathTV.DecMapUint16Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16Float64V(rv2i(rv).(map[uint16]float64), false, d)
+		v := rv.Interface().(map[uint16]float64)
+		fastpathTV.DecMapUint16Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16Float64X(vp *map[uint16]float64, d *Decoder) {
-	v, changed := f.DecMapUint16Float64V(*vp, true, d)
+func (f fastpathT) DecMapUint16Float64X(vp *map[uint16]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, canChange bool,
+func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint16]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint16BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]bool)
-		v, changed := fastpathTV.DecMapUint16BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint16BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint16]bool)
+		v, changed := fastpathTV.DecMapUint16BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint16BoolV(rv2i(rv).(map[uint16]bool), false, d)
+		v := rv.Interface().(map[uint16]bool)
+		fastpathTV.DecMapUint16BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint16BoolX(vp *map[uint16]bool, d *Decoder) {
-	v, changed := f.DecMapUint16BoolV(*vp, true, d)
+func (f fastpathT) DecMapUint16BoolX(vp *map[uint16]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint16BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, canChange bool,
+func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint16]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[uint16]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint16
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint16(dd.DecodeUint(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]interface{})
-		v, changed := fastpathTV.DecMapUint32IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]interface{})
+		v, changed := fastpathTV.DecMapUint32IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32IntfV(rv2i(rv).(map[uint32]interface{}), false, d)
+		v := rv.Interface().(map[uint32]interface{})
+		fastpathTV.DecMapUint32IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32IntfX(vp *map[uint32]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint32IntfV(*vp, true, d)
+func (f fastpathT) DecMapUint32IntfX(vp *map[uint32]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, canChange bool,
+func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[uint32]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk uint32
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]string)
-		v, changed := fastpathTV.DecMapUint32StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]string)
+		v, changed := fastpathTV.DecMapUint32StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32StringV(rv2i(rv).(map[uint32]string), false, d)
+		v := rv.Interface().(map[uint32]string)
+		fastpathTV.DecMapUint32StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32StringX(vp *map[uint32]string, d *Decoder) {
-	v, changed := f.DecMapUint32StringV(*vp, true, d)
+func (f fastpathT) DecMapUint32StringX(vp *map[uint32]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, canChange bool,
+func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[uint32]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint)
-		v, changed := fastpathTV.DecMapUint32UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]uint)
+		v, changed := fastpathTV.DecMapUint32UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32UintV(rv2i(rv).(map[uint32]uint), false, d)
+		v := rv.Interface().(map[uint32]uint)
+		fastpathTV.DecMapUint32UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32UintX(vp *map[uint32]uint, d *Decoder) {
-	v, changed := f.DecMapUint32UintV(*vp, true, d)
+func (f fastpathT) DecMapUint32UintX(vp *map[uint32]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, canChange bool,
+func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint32]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint8)
-		v, changed := fastpathTV.DecMapUint32Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]uint8)
+		v, changed := fastpathTV.DecMapUint32Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Uint8V(rv2i(rv).(map[uint32]uint8), false, d)
+		v := rv.Interface().(map[uint32]uint8)
+		fastpathTV.DecMapUint32Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Uint8X(vp *map[uint32]uint8, d *Decoder) {
-	v, changed := f.DecMapUint32Uint8V(*vp, true, d)
+func (f fastpathT) DecMapUint32Uint8X(vp *map[uint32]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, canChange bool,
+func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[uint32]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint16)
-		v, changed := fastpathTV.DecMapUint32Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]uint16)
+		v, changed := fastpathTV.DecMapUint32Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Uint16V(rv2i(rv).(map[uint32]uint16), false, d)
+		v := rv.Interface().(map[uint32]uint16)
+		fastpathTV.DecMapUint32Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Uint16X(vp *map[uint32]uint16, d *Decoder) {
-	v, changed := f.DecMapUint32Uint16V(*vp, true, d)
+func (f fastpathT) DecMapUint32Uint16X(vp *map[uint32]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, canChange bool,
+func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[uint32]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint32)
-		v, changed := fastpathTV.DecMapUint32Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]uint32)
+		v, changed := fastpathTV.DecMapUint32Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Uint32V(rv2i(rv).(map[uint32]uint32), false, d)
+		v := rv.Interface().(map[uint32]uint32)
+		fastpathTV.DecMapUint32Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Uint32X(vp *map[uint32]uint32, d *Decoder) {
-	v, changed := f.DecMapUint32Uint32V(*vp, true, d)
+func (f fastpathT) DecMapUint32Uint32X(vp *map[uint32]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, canChange bool,
+func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[uint32]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint64)
-		v, changed := fastpathTV.DecMapUint32Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]uint64)
+		v, changed := fastpathTV.DecMapUint32Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Uint64V(rv2i(rv).(map[uint32]uint64), false, d)
+		v := rv.Interface().(map[uint32]uint64)
+		fastpathTV.DecMapUint32Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Uint64X(vp *map[uint32]uint64, d *Decoder) {
-	v, changed := f.DecMapUint32Uint64V(*vp, true, d)
+func (f fastpathT) DecMapUint32Uint64X(vp *map[uint32]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, canChange bool,
+func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint32]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uintptr)
-		v, changed := fastpathTV.DecMapUint32UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]uintptr)
+		v, changed := fastpathTV.DecMapUint32UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32UintptrV(rv2i(rv).(map[uint32]uintptr), false, d)
+		v := rv.Interface().(map[uint32]uintptr)
+		fastpathTV.DecMapUint32UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32UintptrX(vp *map[uint32]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint32UintptrV(*vp, true, d)
+func (f fastpathT) DecMapUint32UintptrX(vp *map[uint32]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32UintptrV(v map[uint32]uintptr, canChange bool,
+func (_ fastpathT) DecMapUint32UintptrV(v map[uint32]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint32]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int)
-		v, changed := fastpathTV.DecMapUint32IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]int)
+		v, changed := fastpathTV.DecMapUint32IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32IntV(rv2i(rv).(map[uint32]int), false, d)
+		v := rv.Interface().(map[uint32]int)
+		fastpathTV.DecMapUint32IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32IntX(vp *map[uint32]int, d *Decoder) {
-	v, changed := f.DecMapUint32IntV(*vp, true, d)
+func (f fastpathT) DecMapUint32IntX(vp *map[uint32]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, canChange bool,
+func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint32]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int8)
-		v, changed := fastpathTV.DecMapUint32Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]int8)
+		v, changed := fastpathTV.DecMapUint32Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Int8V(rv2i(rv).(map[uint32]int8), false, d)
+		v := rv.Interface().(map[uint32]int8)
+		fastpathTV.DecMapUint32Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Int8X(vp *map[uint32]int8, d *Decoder) {
-	v, changed := f.DecMapUint32Int8V(*vp, true, d)
+func (f fastpathT) DecMapUint32Int8X(vp *map[uint32]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, canChange bool,
+func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[uint32]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int16)
-		v, changed := fastpathTV.DecMapUint32Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]int16)
+		v, changed := fastpathTV.DecMapUint32Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Int16V(rv2i(rv).(map[uint32]int16), false, d)
+		v := rv.Interface().(map[uint32]int16)
+		fastpathTV.DecMapUint32Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Int16X(vp *map[uint32]int16, d *Decoder) {
-	v, changed := f.DecMapUint32Int16V(*vp, true, d)
+func (f fastpathT) DecMapUint32Int16X(vp *map[uint32]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, canChange bool,
+func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[uint32]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int32)
-		v, changed := fastpathTV.DecMapUint32Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]int32)
+		v, changed := fastpathTV.DecMapUint32Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Int32V(rv2i(rv).(map[uint32]int32), false, d)
+		v := rv.Interface().(map[uint32]int32)
+		fastpathTV.DecMapUint32Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Int32X(vp *map[uint32]int32, d *Decoder) {
-	v, changed := f.DecMapUint32Int32V(*vp, true, d)
+func (f fastpathT) DecMapUint32Int32X(vp *map[uint32]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, canChange bool,
+func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[uint32]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int64)
-		v, changed := fastpathTV.DecMapUint32Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]int64)
+		v, changed := fastpathTV.DecMapUint32Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Int64V(rv2i(rv).(map[uint32]int64), false, d)
+		v := rv.Interface().(map[uint32]int64)
+		fastpathTV.DecMapUint32Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Int64X(vp *map[uint32]int64, d *Decoder) {
-	v, changed := f.DecMapUint32Int64V(*vp, true, d)
+func (f fastpathT) DecMapUint32Int64X(vp *map[uint32]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, canChange bool,
+func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint32]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]float32)
-		v, changed := fastpathTV.DecMapUint32Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]float32)
+		v, changed := fastpathTV.DecMapUint32Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Float32V(rv2i(rv).(map[uint32]float32), false, d)
+		v := rv.Interface().(map[uint32]float32)
+		fastpathTV.DecMapUint32Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Float32X(vp *map[uint32]float32, d *Decoder) {
-	v, changed := f.DecMapUint32Float32V(*vp, true, d)
+func (f fastpathT) DecMapUint32Float32X(vp *map[uint32]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, canChange bool,
+func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[uint32]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]float64)
-		v, changed := fastpathTV.DecMapUint32Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]float64)
+		v, changed := fastpathTV.DecMapUint32Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32Float64V(rv2i(rv).(map[uint32]float64), false, d)
+		v := rv.Interface().(map[uint32]float64)
+		fastpathTV.DecMapUint32Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32Float64X(vp *map[uint32]float64, d *Decoder) {
-	v, changed := f.DecMapUint32Float64V(*vp, true, d)
+func (f fastpathT) DecMapUint32Float64X(vp *map[uint32]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, canChange bool,
+func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint32]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint32BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]bool)
-		v, changed := fastpathTV.DecMapUint32BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint32BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint32]bool)
+		v, changed := fastpathTV.DecMapUint32BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint32BoolV(rv2i(rv).(map[uint32]bool), false, d)
+		v := rv.Interface().(map[uint32]bool)
+		fastpathTV.DecMapUint32BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint32BoolX(vp *map[uint32]bool, d *Decoder) {
-	v, changed := f.DecMapUint32BoolV(*vp, true, d)
+func (f fastpathT) DecMapUint32BoolX(vp *map[uint32]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint32BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, canChange bool,
+func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint32]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[uint32]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint32
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uint32(dd.DecodeUint(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]interface{})
-		v, changed := fastpathTV.DecMapUint64IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]interface{})
+		v, changed := fastpathTV.DecMapUint64IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64IntfV(rv2i(rv).(map[uint64]interface{}), false, d)
+		v := rv.Interface().(map[uint64]interface{})
+		fastpathTV.DecMapUint64IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64IntfX(vp *map[uint64]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint64IntfV(*vp, true, d)
+func (f fastpathT) DecMapUint64IntfX(vp *map[uint64]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, canChange bool,
+func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[uint64]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk uint64
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]string)
-		v, changed := fastpathTV.DecMapUint64StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]string)
+		v, changed := fastpathTV.DecMapUint64StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64StringV(rv2i(rv).(map[uint64]string), false, d)
+		v := rv.Interface().(map[uint64]string)
+		fastpathTV.DecMapUint64StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64StringX(vp *map[uint64]string, d *Decoder) {
-	v, changed := f.DecMapUint64StringV(*vp, true, d)
+func (f fastpathT) DecMapUint64StringX(vp *map[uint64]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, canChange bool,
+func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[uint64]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint)
-		v, changed := fastpathTV.DecMapUint64UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]uint)
+		v, changed := fastpathTV.DecMapUint64UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64UintV(rv2i(rv).(map[uint64]uint), false, d)
+		v := rv.Interface().(map[uint64]uint)
+		fastpathTV.DecMapUint64UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64UintX(vp *map[uint64]uint, d *Decoder) {
-	v, changed := f.DecMapUint64UintV(*vp, true, d)
+func (f fastpathT) DecMapUint64UintX(vp *map[uint64]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, canChange bool,
+func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint64]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint8)
-		v, changed := fastpathTV.DecMapUint64Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]uint8)
+		v, changed := fastpathTV.DecMapUint64Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Uint8V(rv2i(rv).(map[uint64]uint8), false, d)
+		v := rv.Interface().(map[uint64]uint8)
+		fastpathTV.DecMapUint64Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Uint8X(vp *map[uint64]uint8, d *Decoder) {
-	v, changed := f.DecMapUint64Uint8V(*vp, true, d)
+func (f fastpathT) DecMapUint64Uint8X(vp *map[uint64]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, canChange bool,
+func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint64]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint16)
-		v, changed := fastpathTV.DecMapUint64Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]uint16)
+		v, changed := fastpathTV.DecMapUint64Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Uint16V(rv2i(rv).(map[uint64]uint16), false, d)
+		v := rv.Interface().(map[uint64]uint16)
+		fastpathTV.DecMapUint64Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Uint16X(vp *map[uint64]uint16, d *Decoder) {
-	v, changed := f.DecMapUint64Uint16V(*vp, true, d)
+func (f fastpathT) DecMapUint64Uint16X(vp *map[uint64]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, canChange bool,
+func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint64]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint32)
-		v, changed := fastpathTV.DecMapUint64Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]uint32)
+		v, changed := fastpathTV.DecMapUint64Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Uint32V(rv2i(rv).(map[uint64]uint32), false, d)
+		v := rv.Interface().(map[uint64]uint32)
+		fastpathTV.DecMapUint64Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Uint32X(vp *map[uint64]uint32, d *Decoder) {
-	v, changed := f.DecMapUint64Uint32V(*vp, true, d)
+func (f fastpathT) DecMapUint64Uint32X(vp *map[uint64]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, canChange bool,
+func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint64]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint64)
-		v, changed := fastpathTV.DecMapUint64Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]uint64)
+		v, changed := fastpathTV.DecMapUint64Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Uint64V(rv2i(rv).(map[uint64]uint64), false, d)
+		v := rv.Interface().(map[uint64]uint64)
+		fastpathTV.DecMapUint64Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Uint64X(vp *map[uint64]uint64, d *Decoder) {
-	v, changed := f.DecMapUint64Uint64V(*vp, true, d)
+func (f fastpathT) DecMapUint64Uint64X(vp *map[uint64]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, canChange bool,
+func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint64]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uintptr)
-		v, changed := fastpathTV.DecMapUint64UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]uintptr)
+		v, changed := fastpathTV.DecMapUint64UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64UintptrV(rv2i(rv).(map[uint64]uintptr), false, d)
+		v := rv.Interface().(map[uint64]uintptr)
+		fastpathTV.DecMapUint64UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64UintptrX(vp *map[uint64]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint64UintptrV(*vp, true, d)
+func (f fastpathT) DecMapUint64UintptrX(vp *map[uint64]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
-}
-func (_ fastpathT) DecMapUint64UintptrV(v map[uint64]uintptr, canChange bool,
-	d *Decoder) (_ map[uint64]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+}
+func (_ fastpathT) DecMapUint64UintptrV(v map[uint64]uintptr, checkNil bool, canChange bool,
+	d *Decoder) (_ map[uint64]uintptr, changed bool) {
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint64]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int)
-		v, changed := fastpathTV.DecMapUint64IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]int)
+		v, changed := fastpathTV.DecMapUint64IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64IntV(rv2i(rv).(map[uint64]int), false, d)
+		v := rv.Interface().(map[uint64]int)
+		fastpathTV.DecMapUint64IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64IntX(vp *map[uint64]int, d *Decoder) {
-	v, changed := f.DecMapUint64IntV(*vp, true, d)
+func (f fastpathT) DecMapUint64IntX(vp *map[uint64]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, canChange bool,
+func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint64]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int8)
-		v, changed := fastpathTV.DecMapUint64Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]int8)
+		v, changed := fastpathTV.DecMapUint64Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Int8V(rv2i(rv).(map[uint64]int8), false, d)
+		v := rv.Interface().(map[uint64]int8)
+		fastpathTV.DecMapUint64Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Int8X(vp *map[uint64]int8, d *Decoder) {
-	v, changed := f.DecMapUint64Int8V(*vp, true, d)
+func (f fastpathT) DecMapUint64Int8X(vp *map[uint64]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, canChange bool,
+func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint64]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int16)
-		v, changed := fastpathTV.DecMapUint64Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]int16)
+		v, changed := fastpathTV.DecMapUint64Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Int16V(rv2i(rv).(map[uint64]int16), false, d)
+		v := rv.Interface().(map[uint64]int16)
+		fastpathTV.DecMapUint64Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Int16X(vp *map[uint64]int16, d *Decoder) {
-	v, changed := f.DecMapUint64Int16V(*vp, true, d)
+func (f fastpathT) DecMapUint64Int16X(vp *map[uint64]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, canChange bool,
+func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uint64]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int32)
-		v, changed := fastpathTV.DecMapUint64Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]int32)
+		v, changed := fastpathTV.DecMapUint64Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Int32V(rv2i(rv).(map[uint64]int32), false, d)
+		v := rv.Interface().(map[uint64]int32)
+		fastpathTV.DecMapUint64Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Int32X(vp *map[uint64]int32, d *Decoder) {
-	v, changed := f.DecMapUint64Int32V(*vp, true, d)
+func (f fastpathT) DecMapUint64Int32X(vp *map[uint64]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, canChange bool,
+func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint64]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int64)
-		v, changed := fastpathTV.DecMapUint64Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]int64)
+		v, changed := fastpathTV.DecMapUint64Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Int64V(rv2i(rv).(map[uint64]int64), false, d)
+		v := rv.Interface().(map[uint64]int64)
+		fastpathTV.DecMapUint64Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Int64X(vp *map[uint64]int64, d *Decoder) {
-	v, changed := f.DecMapUint64Int64V(*vp, true, d)
+func (f fastpathT) DecMapUint64Int64X(vp *map[uint64]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, canChange bool,
+func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint64]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]float32)
-		v, changed := fastpathTV.DecMapUint64Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]float32)
+		v, changed := fastpathTV.DecMapUint64Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Float32V(rv2i(rv).(map[uint64]float32), false, d)
+		v := rv.Interface().(map[uint64]float32)
+		fastpathTV.DecMapUint64Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Float32X(vp *map[uint64]float32, d *Decoder) {
-	v, changed := f.DecMapUint64Float32V(*vp, true, d)
+func (f fastpathT) DecMapUint64Float32X(vp *map[uint64]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, canChange bool,
+func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uint64]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]float64)
-		v, changed := fastpathTV.DecMapUint64Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]float64)
+		v, changed := fastpathTV.DecMapUint64Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64Float64V(rv2i(rv).(map[uint64]float64), false, d)
+		v := rv.Interface().(map[uint64]float64)
+		fastpathTV.DecMapUint64Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64Float64X(vp *map[uint64]float64, d *Decoder) {
-	v, changed := f.DecMapUint64Float64V(*vp, true, d)
+func (f fastpathT) DecMapUint64Float64X(vp *map[uint64]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, canChange bool,
+func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uint64]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUint64BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]bool)
-		v, changed := fastpathTV.DecMapUint64BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUint64BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uint64]bool)
+		v, changed := fastpathTV.DecMapUint64BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUint64BoolV(rv2i(rv).(map[uint64]bool), false, d)
+		v := rv.Interface().(map[uint64]bool)
+		fastpathTV.DecMapUint64BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUint64BoolX(vp *map[uint64]bool, d *Decoder) {
-	v, changed := f.DecMapUint64BoolV(*vp, true, d)
+func (f fastpathT) DecMapUint64BoolX(vp *map[uint64]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUint64BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, canChange bool,
+func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uint64]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uint64]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uint64
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeUint(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]interface{})
-		v, changed := fastpathTV.DecMapUintptrIntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrIntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]interface{})
+		v, changed := fastpathTV.DecMapUintptrIntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrIntfV(rv2i(rv).(map[uintptr]interface{}), false, d)
+		v := rv.Interface().(map[uintptr]interface{})
+		fastpathTV.DecMapUintptrIntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrIntfX(vp *map[uintptr]interface{}, d *Decoder) {
-	v, changed := f.DecMapUintptrIntfV(*vp, true, d)
+func (f fastpathT) DecMapUintptrIntfX(vp *map[uintptr]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrIntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrIntfV(v map[uintptr]interface{}, canChange bool,
+func (_ fastpathT) DecMapUintptrIntfV(v map[uintptr]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[uintptr]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk uintptr
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]string)
-		v, changed := fastpathTV.DecMapUintptrStringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrStringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]string)
+		v, changed := fastpathTV.DecMapUintptrStringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrStringV(rv2i(rv).(map[uintptr]string), false, d)
+		v := rv.Interface().(map[uintptr]string)
+		fastpathTV.DecMapUintptrStringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrStringX(vp *map[uintptr]string, d *Decoder) {
-	v, changed := f.DecMapUintptrStringV(*vp, true, d)
+func (f fastpathT) DecMapUintptrStringX(vp *map[uintptr]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrStringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrStringV(v map[uintptr]string, canChange bool,
+func (_ fastpathT) DecMapUintptrStringV(v map[uintptr]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[uintptr]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint)
-		v, changed := fastpathTV.DecMapUintptrUintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrUintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]uint)
+		v, changed := fastpathTV.DecMapUintptrUintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrUintV(rv2i(rv).(map[uintptr]uint), false, d)
+		v := rv.Interface().(map[uintptr]uint)
+		fastpathTV.DecMapUintptrUintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrUintX(vp *map[uintptr]uint, d *Decoder) {
-	v, changed := f.DecMapUintptrUintV(*vp, true, d)
+func (f fastpathT) DecMapUintptrUintX(vp *map[uintptr]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrUintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrUintV(v map[uintptr]uint, canChange bool,
+func (_ fastpathT) DecMapUintptrUintV(v map[uintptr]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uintptr]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint8)
-		v, changed := fastpathTV.DecMapUintptrUint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrUint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]uint8)
+		v, changed := fastpathTV.DecMapUintptrUint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrUint8V(rv2i(rv).(map[uintptr]uint8), false, d)
+		v := rv.Interface().(map[uintptr]uint8)
+		fastpathTV.DecMapUintptrUint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrUint8X(vp *map[uintptr]uint8, d *Decoder) {
-	v, changed := f.DecMapUintptrUint8V(*vp, true, d)
+func (f fastpathT) DecMapUintptrUint8X(vp *map[uintptr]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrUint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrUint8V(v map[uintptr]uint8, canChange bool,
+func (_ fastpathT) DecMapUintptrUint8V(v map[uintptr]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uintptr]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint16)
-		v, changed := fastpathTV.DecMapUintptrUint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrUint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]uint16)
+		v, changed := fastpathTV.DecMapUintptrUint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrUint16V(rv2i(rv).(map[uintptr]uint16), false, d)
+		v := rv.Interface().(map[uintptr]uint16)
+		fastpathTV.DecMapUintptrUint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrUint16X(vp *map[uintptr]uint16, d *Decoder) {
-	v, changed := f.DecMapUintptrUint16V(*vp, true, d)
+func (f fastpathT) DecMapUintptrUint16X(vp *map[uintptr]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrUint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrUint16V(v map[uintptr]uint16, canChange bool,
+func (_ fastpathT) DecMapUintptrUint16V(v map[uintptr]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uintptr]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint32)
-		v, changed := fastpathTV.DecMapUintptrUint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrUint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]uint32)
+		v, changed := fastpathTV.DecMapUintptrUint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrUint32V(rv2i(rv).(map[uintptr]uint32), false, d)
+		v := rv.Interface().(map[uintptr]uint32)
+		fastpathTV.DecMapUintptrUint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrUint32X(vp *map[uintptr]uint32, d *Decoder) {
-	v, changed := f.DecMapUintptrUint32V(*vp, true, d)
+func (f fastpathT) DecMapUintptrUint32X(vp *map[uintptr]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrUint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrUint32V(v map[uintptr]uint32, canChange bool,
+func (_ fastpathT) DecMapUintptrUint32V(v map[uintptr]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uintptr]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint64)
-		v, changed := fastpathTV.DecMapUintptrUint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrUint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]uint64)
+		v, changed := fastpathTV.DecMapUintptrUint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrUint64V(rv2i(rv).(map[uintptr]uint64), false, d)
+		v := rv.Interface().(map[uintptr]uint64)
+		fastpathTV.DecMapUintptrUint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrUint64X(vp *map[uintptr]uint64, d *Decoder) {
-	v, changed := f.DecMapUintptrUint64V(*vp, true, d)
+func (f fastpathT) DecMapUintptrUint64X(vp *map[uintptr]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrUint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrUint64V(v map[uintptr]uint64, canChange bool,
+func (_ fastpathT) DecMapUintptrUint64V(v map[uintptr]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uintptr]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uintptr)
-		v, changed := fastpathTV.DecMapUintptrUintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrUintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]uintptr)
+		v, changed := fastpathTV.DecMapUintptrUintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrUintptrV(rv2i(rv).(map[uintptr]uintptr), false, d)
+		v := rv.Interface().(map[uintptr]uintptr)
+		fastpathTV.DecMapUintptrUintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrUintptrX(vp *map[uintptr]uintptr, d *Decoder) {
-	v, changed := f.DecMapUintptrUintptrV(*vp, true, d)
+func (f fastpathT) DecMapUintptrUintptrX(vp *map[uintptr]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrUintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrUintptrV(v map[uintptr]uintptr, canChange bool,
+func (_ fastpathT) DecMapUintptrUintptrV(v map[uintptr]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uintptr]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int)
-		v, changed := fastpathTV.DecMapUintptrIntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrIntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]int)
+		v, changed := fastpathTV.DecMapUintptrIntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrIntV(rv2i(rv).(map[uintptr]int), false, d)
+		v := rv.Interface().(map[uintptr]int)
+		fastpathTV.DecMapUintptrIntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrIntX(vp *map[uintptr]int, d *Decoder) {
-	v, changed := f.DecMapUintptrIntV(*vp, true, d)
+func (f fastpathT) DecMapUintptrIntX(vp *map[uintptr]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrIntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrIntV(v map[uintptr]int, canChange bool,
+func (_ fastpathT) DecMapUintptrIntV(v map[uintptr]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uintptr]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int8)
-		v, changed := fastpathTV.DecMapUintptrInt8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrInt8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]int8)
+		v, changed := fastpathTV.DecMapUintptrInt8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrInt8V(rv2i(rv).(map[uintptr]int8), false, d)
+		v := rv.Interface().(map[uintptr]int8)
+		fastpathTV.DecMapUintptrInt8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrInt8X(vp *map[uintptr]int8, d *Decoder) {
-	v, changed := f.DecMapUintptrInt8V(*vp, true, d)
+func (f fastpathT) DecMapUintptrInt8X(vp *map[uintptr]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrInt8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrInt8V(v map[uintptr]int8, canChange bool,
+func (_ fastpathT) DecMapUintptrInt8V(v map[uintptr]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uintptr]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int16)
-		v, changed := fastpathTV.DecMapUintptrInt16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrInt16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]int16)
+		v, changed := fastpathTV.DecMapUintptrInt16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrInt16V(rv2i(rv).(map[uintptr]int16), false, d)
+		v := rv.Interface().(map[uintptr]int16)
+		fastpathTV.DecMapUintptrInt16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrInt16X(vp *map[uintptr]int16, d *Decoder) {
-	v, changed := f.DecMapUintptrInt16V(*vp, true, d)
+func (f fastpathT) DecMapUintptrInt16X(vp *map[uintptr]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrInt16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrInt16V(v map[uintptr]int16, canChange bool,
+func (_ fastpathT) DecMapUintptrInt16V(v map[uintptr]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[uintptr]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int32)
-		v, changed := fastpathTV.DecMapUintptrInt32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrInt32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]int32)
+		v, changed := fastpathTV.DecMapUintptrInt32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrInt32V(rv2i(rv).(map[uintptr]int32), false, d)
+		v := rv.Interface().(map[uintptr]int32)
+		fastpathTV.DecMapUintptrInt32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrInt32X(vp *map[uintptr]int32, d *Decoder) {
-	v, changed := f.DecMapUintptrInt32V(*vp, true, d)
+func (f fastpathT) DecMapUintptrInt32X(vp *map[uintptr]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrInt32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrInt32V(v map[uintptr]int32, canChange bool,
+func (_ fastpathT) DecMapUintptrInt32V(v map[uintptr]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uintptr]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int64)
-		v, changed := fastpathTV.DecMapUintptrInt64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrInt64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]int64)
+		v, changed := fastpathTV.DecMapUintptrInt64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrInt64V(rv2i(rv).(map[uintptr]int64), false, d)
+		v := rv.Interface().(map[uintptr]int64)
+		fastpathTV.DecMapUintptrInt64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrInt64X(vp *map[uintptr]int64, d *Decoder) {
-	v, changed := f.DecMapUintptrInt64V(*vp, true, d)
+func (f fastpathT) DecMapUintptrInt64X(vp *map[uintptr]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrInt64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrInt64V(v map[uintptr]int64, canChange bool,
+func (_ fastpathT) DecMapUintptrInt64V(v map[uintptr]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uintptr]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]float32)
-		v, changed := fastpathTV.DecMapUintptrFloat32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrFloat32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]float32)
+		v, changed := fastpathTV.DecMapUintptrFloat32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrFloat32V(rv2i(rv).(map[uintptr]float32), false, d)
+		v := rv.Interface().(map[uintptr]float32)
+		fastpathTV.DecMapUintptrFloat32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrFloat32X(vp *map[uintptr]float32, d *Decoder) {
-	v, changed := f.DecMapUintptrFloat32V(*vp, true, d)
+func (f fastpathT) DecMapUintptrFloat32X(vp *map[uintptr]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrFloat32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrFloat32V(v map[uintptr]float32, canChange bool,
+func (_ fastpathT) DecMapUintptrFloat32V(v map[uintptr]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[uintptr]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]float64)
-		v, changed := fastpathTV.DecMapUintptrFloat64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrFloat64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]float64)
+		v, changed := fastpathTV.DecMapUintptrFloat64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrFloat64V(rv2i(rv).(map[uintptr]float64), false, d)
+		v := rv.Interface().(map[uintptr]float64)
+		fastpathTV.DecMapUintptrFloat64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrFloat64X(vp *map[uintptr]float64, d *Decoder) {
-	v, changed := f.DecMapUintptrFloat64V(*vp, true, d)
+func (f fastpathT) DecMapUintptrFloat64X(vp *map[uintptr]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrFloat64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrFloat64V(v map[uintptr]float64, canChange bool,
+func (_ fastpathT) DecMapUintptrFloat64V(v map[uintptr]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[uintptr]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapUintptrBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]bool)
-		v, changed := fastpathTV.DecMapUintptrBoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapUintptrBoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[uintptr]bool)
+		v, changed := fastpathTV.DecMapUintptrBoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapUintptrBoolV(rv2i(rv).(map[uintptr]bool), false, d)
+		v := rv.Interface().(map[uintptr]bool)
+		fastpathTV.DecMapUintptrBoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapUintptrBoolX(vp *map[uintptr]bool, d *Decoder) {
-	v, changed := f.DecMapUintptrBoolV(*vp, true, d)
+func (f fastpathT) DecMapUintptrBoolX(vp *map[uintptr]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapUintptrBoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapUintptrBoolV(v map[uintptr]bool, canChange bool,
+func (_ fastpathT) DecMapUintptrBoolV(v map[uintptr]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[uintptr]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[uintptr]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk uintptr
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = uintptr(dd.DecodeUint(uintBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]interface{})
-		v, changed := fastpathTV.DecMapIntIntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntIntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]interface{})
+		v, changed := fastpathTV.DecMapIntIntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntIntfV(rv2i(rv).(map[int]interface{}), false, d)
+		v := rv.Interface().(map[int]interface{})
+		fastpathTV.DecMapIntIntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntIntfX(vp *map[int]interface{}, d *Decoder) {
-	v, changed := f.DecMapIntIntfV(*vp, true, d)
+func (f fastpathT) DecMapIntIntfX(vp *map[int]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntIntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, canChange bool,
+func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[int]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk int
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]string)
-		v, changed := fastpathTV.DecMapIntStringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntStringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]string)
+		v, changed := fastpathTV.DecMapIntStringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntStringV(rv2i(rv).(map[int]string), false, d)
+		v := rv.Interface().(map[int]string)
+		fastpathTV.DecMapIntStringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntStringX(vp *map[int]string, d *Decoder) {
-	v, changed := f.DecMapIntStringV(*vp, true, d)
+func (f fastpathT) DecMapIntStringX(vp *map[int]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntStringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntStringV(v map[int]string, canChange bool,
+func (_ fastpathT) DecMapIntStringV(v map[int]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[int]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint)
-		v, changed := fastpathTV.DecMapIntUintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntUintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]uint)
+		v, changed := fastpathTV.DecMapIntUintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntUintV(rv2i(rv).(map[int]uint), false, d)
+		v := rv.Interface().(map[int]uint)
+		fastpathTV.DecMapIntUintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntUintX(vp *map[int]uint, d *Decoder) {
-	v, changed := f.DecMapIntUintV(*vp, true, d)
+func (f fastpathT) DecMapIntUintX(vp *map[int]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntUintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntUintV(v map[int]uint, canChange bool,
+func (_ fastpathT) DecMapIntUintV(v map[int]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint8)
-		v, changed := fastpathTV.DecMapIntUint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntUint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]uint8)
+		v, changed := fastpathTV.DecMapIntUint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntUint8V(rv2i(rv).(map[int]uint8), false, d)
+		v := rv.Interface().(map[int]uint8)
+		fastpathTV.DecMapIntUint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntUint8X(vp *map[int]uint8, d *Decoder) {
-	v, changed := f.DecMapIntUint8V(*vp, true, d)
+func (f fastpathT) DecMapIntUint8X(vp *map[int]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntUint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, canChange bool,
+func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint16)
-		v, changed := fastpathTV.DecMapIntUint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntUint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]uint16)
+		v, changed := fastpathTV.DecMapIntUint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntUint16V(rv2i(rv).(map[int]uint16), false, d)
+		v := rv.Interface().(map[int]uint16)
+		fastpathTV.DecMapIntUint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntUint16X(vp *map[int]uint16, d *Decoder) {
-	v, changed := f.DecMapIntUint16V(*vp, true, d)
+func (f fastpathT) DecMapIntUint16X(vp *map[int]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntUint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, canChange bool,
+func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint32)
-		v, changed := fastpathTV.DecMapIntUint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntUint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]uint32)
+		v, changed := fastpathTV.DecMapIntUint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntUint32V(rv2i(rv).(map[int]uint32), false, d)
+		v := rv.Interface().(map[int]uint32)
+		fastpathTV.DecMapIntUint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntUint32X(vp *map[int]uint32, d *Decoder) {
-	v, changed := f.DecMapIntUint32V(*vp, true, d)
+func (f fastpathT) DecMapIntUint32X(vp *map[int]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntUint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, canChange bool,
+func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint64)
-		v, changed := fastpathTV.DecMapIntUint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntUint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]uint64)
+		v, changed := fastpathTV.DecMapIntUint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntUint64V(rv2i(rv).(map[int]uint64), false, d)
+		v := rv.Interface().(map[int]uint64)
+		fastpathTV.DecMapIntUint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntUint64X(vp *map[int]uint64, d *Decoder) {
-	v, changed := f.DecMapIntUint64V(*vp, true, d)
+func (f fastpathT) DecMapIntUint64X(vp *map[int]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntUint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, canChange bool,
+func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uintptr)
-		v, changed := fastpathTV.DecMapIntUintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntUintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]uintptr)
+		v, changed := fastpathTV.DecMapIntUintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntUintptrV(rv2i(rv).(map[int]uintptr), false, d)
+		v := rv.Interface().(map[int]uintptr)
+		fastpathTV.DecMapIntUintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntUintptrX(vp *map[int]uintptr, d *Decoder) {
-	v, changed := f.DecMapIntUintptrV(*vp, true, d)
+func (f fastpathT) DecMapIntUintptrX(vp *map[int]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntUintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntUintptrV(v map[int]uintptr, canChange bool,
+func (_ fastpathT) DecMapIntUintptrV(v map[int]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int)
-		v, changed := fastpathTV.DecMapIntIntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntIntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]int)
+		v, changed := fastpathTV.DecMapIntIntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntIntV(rv2i(rv).(map[int]int), false, d)
+		v := rv.Interface().(map[int]int)
+		fastpathTV.DecMapIntIntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntIntX(vp *map[int]int, d *Decoder) {
-	v, changed := f.DecMapIntIntV(*vp, true, d)
+func (f fastpathT) DecMapIntIntX(vp *map[int]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntIntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntIntV(v map[int]int, canChange bool,
+func (_ fastpathT) DecMapIntIntV(v map[int]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int8)
-		v, changed := fastpathTV.DecMapIntInt8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntInt8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]int8)
+		v, changed := fastpathTV.DecMapIntInt8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntInt8V(rv2i(rv).(map[int]int8), false, d)
+		v := rv.Interface().(map[int]int8)
+		fastpathTV.DecMapIntInt8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntInt8X(vp *map[int]int8, d *Decoder) {
-	v, changed := f.DecMapIntInt8V(*vp, true, d)
+func (f fastpathT) DecMapIntInt8X(vp *map[int]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntInt8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntInt8V(v map[int]int8, canChange bool,
+func (_ fastpathT) DecMapIntInt8V(v map[int]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int16)
-		v, changed := fastpathTV.DecMapIntInt16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntInt16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]int16)
+		v, changed := fastpathTV.DecMapIntInt16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntInt16V(rv2i(rv).(map[int]int16), false, d)
+		v := rv.Interface().(map[int]int16)
+		fastpathTV.DecMapIntInt16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntInt16X(vp *map[int]int16, d *Decoder) {
-	v, changed := f.DecMapIntInt16V(*vp, true, d)
+func (f fastpathT) DecMapIntInt16X(vp *map[int]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntInt16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntInt16V(v map[int]int16, canChange bool,
+func (_ fastpathT) DecMapIntInt16V(v map[int]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int32)
-		v, changed := fastpathTV.DecMapIntInt32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntInt32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]int32)
+		v, changed := fastpathTV.DecMapIntInt32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntInt32V(rv2i(rv).(map[int]int32), false, d)
+		v := rv.Interface().(map[int]int32)
+		fastpathTV.DecMapIntInt32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntInt32X(vp *map[int]int32, d *Decoder) {
-	v, changed := f.DecMapIntInt32V(*vp, true, d)
+func (f fastpathT) DecMapIntInt32X(vp *map[int]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntInt32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntInt32V(v map[int]int32, canChange bool,
+func (_ fastpathT) DecMapIntInt32V(v map[int]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
+		changed = true
 	}
+
 	var mk int
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int64)
-		v, changed := fastpathTV.DecMapIntInt64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntInt64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]int64)
+		v, changed := fastpathTV.DecMapIntInt64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntInt64V(rv2i(rv).(map[int]int64), false, d)
+		v := rv.Interface().(map[int]int64)
+		fastpathTV.DecMapIntInt64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntInt64X(vp *map[int]int64, d *Decoder) {
-	v, changed := f.DecMapIntInt64V(*vp, true, d)
+func (f fastpathT) DecMapIntInt64X(vp *map[int]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntInt64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntInt64V(v map[int]int64, canChange bool,
+func (_ fastpathT) DecMapIntInt64V(v map[int]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]float32)
-		v, changed := fastpathTV.DecMapIntFloat32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntFloat32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]float32)
+		v, changed := fastpathTV.DecMapIntFloat32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntFloat32V(rv2i(rv).(map[int]float32), false, d)
+		v := rv.Interface().(map[int]float32)
+		fastpathTV.DecMapIntFloat32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntFloat32X(vp *map[int]float32, d *Decoder) {
-	v, changed := f.DecMapIntFloat32V(*vp, true, d)
+func (f fastpathT) DecMapIntFloat32X(vp *map[int]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntFloat32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, canChange bool,
+func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]float64)
-		v, changed := fastpathTV.DecMapIntFloat64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntFloat64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]float64)
+		v, changed := fastpathTV.DecMapIntFloat64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntFloat64V(rv2i(rv).(map[int]float64), false, d)
+		v := rv.Interface().(map[int]float64)
+		fastpathTV.DecMapIntFloat64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntFloat64X(vp *map[int]float64, d *Decoder) {
-	v, changed := f.DecMapIntFloat64V(*vp, true, d)
+func (f fastpathT) DecMapIntFloat64X(vp *map[int]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntFloat64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, canChange bool,
+func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapIntBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]bool)
-		v, changed := fastpathTV.DecMapIntBoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapIntBoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int]bool)
+		v, changed := fastpathTV.DecMapIntBoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapIntBoolV(rv2i(rv).(map[int]bool), false, d)
+		v := rv.Interface().(map[int]bool)
+		fastpathTV.DecMapIntBoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapIntBoolX(vp *map[int]bool, d *Decoder) {
-	v, changed := f.DecMapIntBoolV(*vp, true, d)
+func (f fastpathT) DecMapIntBoolX(vp *map[int]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapIntBoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapIntBoolV(v map[int]bool, canChange bool,
+func (_ fastpathT) DecMapIntBoolV(v map[int]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int(dd.DecodeInt(intBitsize))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]interface{})
-		v, changed := fastpathTV.DecMapInt8IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]interface{})
+		v, changed := fastpathTV.DecMapInt8IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8IntfV(rv2i(rv).(map[int8]interface{}), false, d)
+		v := rv.Interface().(map[int8]interface{})
+		fastpathTV.DecMapInt8IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8IntfX(vp *map[int8]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt8IntfV(*vp, true, d)
+func (f fastpathT) DecMapInt8IntfX(vp *map[int8]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, canChange bool,
+func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[int8]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk int8
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]string)
-		v, changed := fastpathTV.DecMapInt8StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]string)
+		v, changed := fastpathTV.DecMapInt8StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8StringV(rv2i(rv).(map[int8]string), false, d)
+		v := rv.Interface().(map[int8]string)
+		fastpathTV.DecMapInt8StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8StringX(vp *map[int8]string, d *Decoder) {
-	v, changed := f.DecMapInt8StringV(*vp, true, d)
+func (f fastpathT) DecMapInt8StringX(vp *map[int8]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8StringV(v map[int8]string, canChange bool,
+func (_ fastpathT) DecMapInt8StringV(v map[int8]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[int8]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint)
-		v, changed := fastpathTV.DecMapInt8UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]uint)
+		v, changed := fastpathTV.DecMapInt8UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8UintV(rv2i(rv).(map[int8]uint), false, d)
+		v := rv.Interface().(map[int8]uint)
+		fastpathTV.DecMapInt8UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8UintX(vp *map[int8]uint, d *Decoder) {
-	v, changed := f.DecMapInt8UintV(*vp, true, d)
+func (f fastpathT) DecMapInt8UintX(vp *map[int8]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, canChange bool,
+func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int8]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint8)
-		v, changed := fastpathTV.DecMapInt8Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]uint8)
+		v, changed := fastpathTV.DecMapInt8Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Uint8V(rv2i(rv).(map[int8]uint8), false, d)
+		v := rv.Interface().(map[int8]uint8)
+		fastpathTV.DecMapInt8Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Uint8X(vp *map[int8]uint8, d *Decoder) {
-	v, changed := f.DecMapInt8Uint8V(*vp, true, d)
+func (f fastpathT) DecMapInt8Uint8X(vp *map[int8]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, canChange bool,
+func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[int8]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint16)
-		v, changed := fastpathTV.DecMapInt8Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]uint16)
+		v, changed := fastpathTV.DecMapInt8Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Uint16V(rv2i(rv).(map[int8]uint16), false, d)
+		v := rv.Interface().(map[int8]uint16)
+		fastpathTV.DecMapInt8Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Uint16X(vp *map[int8]uint16, d *Decoder) {
-	v, changed := f.DecMapInt8Uint16V(*vp, true, d)
+func (f fastpathT) DecMapInt8Uint16X(vp *map[int8]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, canChange bool,
+func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[int8]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint32)
-		v, changed := fastpathTV.DecMapInt8Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]uint32)
+		v, changed := fastpathTV.DecMapInt8Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Uint32V(rv2i(rv).(map[int8]uint32), false, d)
+		v := rv.Interface().(map[int8]uint32)
+		fastpathTV.DecMapInt8Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Uint32X(vp *map[int8]uint32, d *Decoder) {
-	v, changed := f.DecMapInt8Uint32V(*vp, true, d)
+func (f fastpathT) DecMapInt8Uint32X(vp *map[int8]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, canChange bool,
+func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[int8]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint64)
-		v, changed := fastpathTV.DecMapInt8Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]uint64)
+		v, changed := fastpathTV.DecMapInt8Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Uint64V(rv2i(rv).(map[int8]uint64), false, d)
+		v := rv.Interface().(map[int8]uint64)
+		fastpathTV.DecMapInt8Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Uint64X(vp *map[int8]uint64, d *Decoder) {
-	v, changed := f.DecMapInt8Uint64V(*vp, true, d)
+func (f fastpathT) DecMapInt8Uint64X(vp *map[int8]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, canChange bool,
+func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int8]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uintptr)
-		v, changed := fastpathTV.DecMapInt8UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]uintptr)
+		v, changed := fastpathTV.DecMapInt8UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8UintptrV(rv2i(rv).(map[int8]uintptr), false, d)
+		v := rv.Interface().(map[int8]uintptr)
+		fastpathTV.DecMapInt8UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8UintptrX(vp *map[int8]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt8UintptrV(*vp, true, d)
+func (f fastpathT) DecMapInt8UintptrX(vp *map[int8]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8UintptrV(v map[int8]uintptr, canChange bool,
+func (_ fastpathT) DecMapInt8UintptrV(v map[int8]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int8]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int)
-		v, changed := fastpathTV.DecMapInt8IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]int)
+		v, changed := fastpathTV.DecMapInt8IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8IntV(rv2i(rv).(map[int8]int), false, d)
+		v := rv.Interface().(map[int8]int)
+		fastpathTV.DecMapInt8IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8IntX(vp *map[int8]int, d *Decoder) {
-	v, changed := f.DecMapInt8IntV(*vp, true, d)
+func (f fastpathT) DecMapInt8IntX(vp *map[int8]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8IntV(v map[int8]int, canChange bool,
+func (_ fastpathT) DecMapInt8IntV(v map[int8]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int8]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int8)
-		v, changed := fastpathTV.DecMapInt8Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]int8)
+		v, changed := fastpathTV.DecMapInt8Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Int8V(rv2i(rv).(map[int8]int8), false, d)
+		v := rv.Interface().(map[int8]int8)
+		fastpathTV.DecMapInt8Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Int8X(vp *map[int8]int8, d *Decoder) {
-	v, changed := f.DecMapInt8Int8V(*vp, true, d)
+func (f fastpathT) DecMapInt8Int8X(vp *map[int8]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, canChange bool,
+func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[int8]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int16)
-		v, changed := fastpathTV.DecMapInt8Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]int16)
+		v, changed := fastpathTV.DecMapInt8Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Int16V(rv2i(rv).(map[int8]int16), false, d)
+		v := rv.Interface().(map[int8]int16)
+		fastpathTV.DecMapInt8Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Int16X(vp *map[int8]int16, d *Decoder) {
-	v, changed := f.DecMapInt8Int16V(*vp, true, d)
+func (f fastpathT) DecMapInt8Int16X(vp *map[int8]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, canChange bool,
+func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[int8]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int32)
-		v, changed := fastpathTV.DecMapInt8Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]int32)
+		v, changed := fastpathTV.DecMapInt8Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Int32V(rv2i(rv).(map[int8]int32), false, d)
+		v := rv.Interface().(map[int8]int32)
+		fastpathTV.DecMapInt8Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Int32X(vp *map[int8]int32, d *Decoder) {
-	v, changed := f.DecMapInt8Int32V(*vp, true, d)
+func (f fastpathT) DecMapInt8Int32X(vp *map[int8]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, canChange bool,
+func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[int8]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int64)
-		v, changed := fastpathTV.DecMapInt8Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]int64)
+		v, changed := fastpathTV.DecMapInt8Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Int64V(rv2i(rv).(map[int8]int64), false, d)
+		v := rv.Interface().(map[int8]int64)
+		fastpathTV.DecMapInt8Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Int64X(vp *map[int8]int64, d *Decoder) {
-	v, changed := f.DecMapInt8Int64V(*vp, true, d)
+func (f fastpathT) DecMapInt8Int64X(vp *map[int8]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, canChange bool,
+func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int8]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]float32)
-		v, changed := fastpathTV.DecMapInt8Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]float32)
+		v, changed := fastpathTV.DecMapInt8Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Float32V(rv2i(rv).(map[int8]float32), false, d)
+		v := rv.Interface().(map[int8]float32)
+		fastpathTV.DecMapInt8Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Float32X(vp *map[int8]float32, d *Decoder) {
-	v, changed := f.DecMapInt8Float32V(*vp, true, d)
+func (f fastpathT) DecMapInt8Float32X(vp *map[int8]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, canChange bool,
+func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[int8]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]float64)
-		v, changed := fastpathTV.DecMapInt8Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]float64)
+		v, changed := fastpathTV.DecMapInt8Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8Float64V(rv2i(rv).(map[int8]float64), false, d)
+		v := rv.Interface().(map[int8]float64)
+		fastpathTV.DecMapInt8Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8Float64X(vp *map[int8]float64, d *Decoder) {
-	v, changed := f.DecMapInt8Float64V(*vp, true, d)
+func (f fastpathT) DecMapInt8Float64X(vp *map[int8]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, canChange bool,
+func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int8]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt8BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]bool)
-		v, changed := fastpathTV.DecMapInt8BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt8BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int8]bool)
+		v, changed := fastpathTV.DecMapInt8BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt8BoolV(rv2i(rv).(map[int8]bool), false, d)
+		v := rv.Interface().(map[int8]bool)
+		fastpathTV.DecMapInt8BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt8BoolX(vp *map[int8]bool, d *Decoder) {
-	v, changed := f.DecMapInt8BoolV(*vp, true, d)
+func (f fastpathT) DecMapInt8BoolX(vp *map[int8]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt8BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, canChange bool,
+func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int8]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[int8]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int8
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int8(dd.DecodeInt(8))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]interface{})
-		v, changed := fastpathTV.DecMapInt16IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]interface{})
+		v, changed := fastpathTV.DecMapInt16IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16IntfV(rv2i(rv).(map[int16]interface{}), false, d)
+		v := rv.Interface().(map[int16]interface{})
+		fastpathTV.DecMapInt16IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16IntfX(vp *map[int16]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt16IntfV(*vp, true, d)
+func (f fastpathT) DecMapInt16IntfX(vp *map[int16]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, canChange bool,
+func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[int16]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk int16
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]string)
-		v, changed := fastpathTV.DecMapInt16StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]string)
+		v, changed := fastpathTV.DecMapInt16StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16StringV(rv2i(rv).(map[int16]string), false, d)
+		v := rv.Interface().(map[int16]string)
+		fastpathTV.DecMapInt16StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16StringX(vp *map[int16]string, d *Decoder) {
-	v, changed := f.DecMapInt16StringV(*vp, true, d)
+func (f fastpathT) DecMapInt16StringX(vp *map[int16]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16StringV(v map[int16]string, canChange bool,
+func (_ fastpathT) DecMapInt16StringV(v map[int16]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18)
 		v = make(map[int16]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint)
-		v, changed := fastpathTV.DecMapInt16UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]uint)
+		v, changed := fastpathTV.DecMapInt16UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16UintV(rv2i(rv).(map[int16]uint), false, d)
+		v := rv.Interface().(map[int16]uint)
+		fastpathTV.DecMapInt16UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16UintX(vp *map[int16]uint, d *Decoder) {
-	v, changed := f.DecMapInt16UintV(*vp, true, d)
+func (f fastpathT) DecMapInt16UintX(vp *map[int16]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, canChange bool,
+func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int16]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint8)
-		v, changed := fastpathTV.DecMapInt16Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]uint8)
+		v, changed := fastpathTV.DecMapInt16Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Uint8V(rv2i(rv).(map[int16]uint8), false, d)
+		v := rv.Interface().(map[int16]uint8)
+		fastpathTV.DecMapInt16Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Uint8X(vp *map[int16]uint8, d *Decoder) {
-	v, changed := f.DecMapInt16Uint8V(*vp, true, d)
+func (f fastpathT) DecMapInt16Uint8X(vp *map[int16]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, canChange bool,
+func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[int16]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint16)
-		v, changed := fastpathTV.DecMapInt16Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]uint16)
+		v, changed := fastpathTV.DecMapInt16Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Uint16V(rv2i(rv).(map[int16]uint16), false, d)
+		v := rv.Interface().(map[int16]uint16)
+		fastpathTV.DecMapInt16Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Uint16X(vp *map[int16]uint16, d *Decoder) {
-	v, changed := f.DecMapInt16Uint16V(*vp, true, d)
+func (f fastpathT) DecMapInt16Uint16X(vp *map[int16]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, canChange bool,
+func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4)
 		v = make(map[int16]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint32)
-		v, changed := fastpathTV.DecMapInt16Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]uint32)
+		v, changed := fastpathTV.DecMapInt16Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Uint32V(rv2i(rv).(map[int16]uint32), false, d)
+		v := rv.Interface().(map[int16]uint32)
+		fastpathTV.DecMapInt16Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Uint32X(vp *map[int16]uint32, d *Decoder) {
-	v, changed := f.DecMapInt16Uint32V(*vp, true, d)
+func (f fastpathT) DecMapInt16Uint32X(vp *map[int16]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, canChange bool,
+func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[int16]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint64)
-		v, changed := fastpathTV.DecMapInt16Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]uint64)
+		v, changed := fastpathTV.DecMapInt16Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Uint64V(rv2i(rv).(map[int16]uint64), false, d)
+		v := rv.Interface().(map[int16]uint64)
+		fastpathTV.DecMapInt16Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Uint64X(vp *map[int16]uint64, d *Decoder) {
-	v, changed := f.DecMapInt16Uint64V(*vp, true, d)
+func (f fastpathT) DecMapInt16Uint64X(vp *map[int16]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, canChange bool,
+func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int16]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uintptr)
-		v, changed := fastpathTV.DecMapInt16UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]uintptr)
+		v, changed := fastpathTV.DecMapInt16UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16UintptrV(rv2i(rv).(map[int16]uintptr), false, d)
+		v := rv.Interface().(map[int16]uintptr)
+		fastpathTV.DecMapInt16UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16UintptrX(vp *map[int16]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt16UintptrV(*vp, true, d)
+func (f fastpathT) DecMapInt16UintptrX(vp *map[int16]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16UintptrV(v map[int16]uintptr, canChange bool,
+func (_ fastpathT) DecMapInt16UintptrV(v map[int16]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int16]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int)
-		v, changed := fastpathTV.DecMapInt16IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]int)
+		v, changed := fastpathTV.DecMapInt16IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16IntV(rv2i(rv).(map[int16]int), false, d)
+		v := rv.Interface().(map[int16]int)
+		fastpathTV.DecMapInt16IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16IntX(vp *map[int16]int, d *Decoder) {
-	v, changed := f.DecMapInt16IntV(*vp, true, d)
+func (f fastpathT) DecMapInt16IntX(vp *map[int16]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16IntV(v map[int16]int, canChange bool,
+func (_ fastpathT) DecMapInt16IntV(v map[int16]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int16]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int8)
-		v, changed := fastpathTV.DecMapInt16Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]int8)
+		v, changed := fastpathTV.DecMapInt16Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Int8V(rv2i(rv).(map[int16]int8), false, d)
+		v := rv.Interface().(map[int16]int8)
+		fastpathTV.DecMapInt16Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Int8X(vp *map[int16]int8, d *Decoder) {
-	v, changed := f.DecMapInt16Int8V(*vp, true, d)
+func (f fastpathT) DecMapInt16Int8X(vp *map[int16]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, canChange bool,
+func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[int16]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int16)
-		v, changed := fastpathTV.DecMapInt16Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]int16)
+		v, changed := fastpathTV.DecMapInt16Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Int16V(rv2i(rv).(map[int16]int16), false, d)
+		v := rv.Interface().(map[int16]int16)
+		fastpathTV.DecMapInt16Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Int16X(vp *map[int16]int16, d *Decoder) {
-	v, changed := f.DecMapInt16Int16V(*vp, true, d)
+func (f fastpathT) DecMapInt16Int16X(vp *map[int16]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, canChange bool,
+func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4)
 		v = make(map[int16]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int32)
-		v, changed := fastpathTV.DecMapInt16Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]int32)
+		v, changed := fastpathTV.DecMapInt16Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Int32V(rv2i(rv).(map[int16]int32), false, d)
+		v := rv.Interface().(map[int16]int32)
+		fastpathTV.DecMapInt16Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Int32X(vp *map[int16]int32, d *Decoder) {
-	v, changed := f.DecMapInt16Int32V(*vp, true, d)
+func (f fastpathT) DecMapInt16Int32X(vp *map[int16]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, canChange bool,
+func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[int16]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int64)
-		v, changed := fastpathTV.DecMapInt16Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]int64)
+		v, changed := fastpathTV.DecMapInt16Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Int64V(rv2i(rv).(map[int16]int64), false, d)
+		v := rv.Interface().(map[int16]int64)
+		fastpathTV.DecMapInt16Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Int64X(vp *map[int16]int64, d *Decoder) {
-	v, changed := f.DecMapInt16Int64V(*vp, true, d)
+func (f fastpathT) DecMapInt16Int64X(vp *map[int16]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, canChange bool,
+func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int16]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]float32)
-		v, changed := fastpathTV.DecMapInt16Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]float32)
+		v, changed := fastpathTV.DecMapInt16Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Float32V(rv2i(rv).(map[int16]float32), false, d)
+		v := rv.Interface().(map[int16]float32)
+		fastpathTV.DecMapInt16Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Float32X(vp *map[int16]float32, d *Decoder) {
-	v, changed := f.DecMapInt16Float32V(*vp, true, d)
+func (f fastpathT) DecMapInt16Float32X(vp *map[int16]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, canChange bool,
+func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[int16]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]float64)
-		v, changed := fastpathTV.DecMapInt16Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]float64)
+		v, changed := fastpathTV.DecMapInt16Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16Float64V(rv2i(rv).(map[int16]float64), false, d)
+		v := rv.Interface().(map[int16]float64)
+		fastpathTV.DecMapInt16Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16Float64X(vp *map[int16]float64, d *Decoder) {
-	v, changed := f.DecMapInt16Float64V(*vp, true, d)
+func (f fastpathT) DecMapInt16Float64X(vp *map[int16]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, canChange bool,
+func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int16]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt16BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]bool)
-		v, changed := fastpathTV.DecMapInt16BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt16BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int16]bool)
+		v, changed := fastpathTV.DecMapInt16BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt16BoolV(rv2i(rv).(map[int16]bool), false, d)
+		v := rv.Interface().(map[int16]bool)
+		fastpathTV.DecMapInt16BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt16BoolX(vp *map[int16]bool, d *Decoder) {
-	v, changed := f.DecMapInt16BoolV(*vp, true, d)
+func (f fastpathT) DecMapInt16BoolX(vp *map[int16]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt16BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, canChange bool,
+func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int16]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[int16]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int16
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int16(dd.DecodeInt(16))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]interface{})
-		v, changed := fastpathTV.DecMapInt32IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]interface{})
+		v, changed := fastpathTV.DecMapInt32IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32IntfV(rv2i(rv).(map[int32]interface{}), false, d)
+		v := rv.Interface().(map[int32]interface{})
+		fastpathTV.DecMapInt32IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32IntfX(vp *map[int32]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt32IntfV(*vp, true, d)
+func (f fastpathT) DecMapInt32IntfX(vp *map[int32]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, canChange bool,
+func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[int32]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk int32
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]string)
-		v, changed := fastpathTV.DecMapInt32StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]string)
+		v, changed := fastpathTV.DecMapInt32StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32StringV(rv2i(rv).(map[int32]string), false, d)
+		v := rv.Interface().(map[int32]string)
+		fastpathTV.DecMapInt32StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32StringX(vp *map[int32]string, d *Decoder) {
-	v, changed := f.DecMapInt32StringV(*vp, true, d)
+func (f fastpathT) DecMapInt32StringX(vp *map[int32]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32StringV(v map[int32]string, canChange bool,
+func (_ fastpathT) DecMapInt32StringV(v map[int32]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20)
 		v = make(map[int32]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint)
-		v, changed := fastpathTV.DecMapInt32UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]uint)
+		v, changed := fastpathTV.DecMapInt32UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32UintV(rv2i(rv).(map[int32]uint), false, d)
+		v := rv.Interface().(map[int32]uint)
+		fastpathTV.DecMapInt32UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32UintX(vp *map[int32]uint, d *Decoder) {
-	v, changed := f.DecMapInt32UintV(*vp, true, d)
+func (f fastpathT) DecMapInt32UintX(vp *map[int32]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, canChange bool,
+func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int32]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint8)
-		v, changed := fastpathTV.DecMapInt32Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]uint8)
+		v, changed := fastpathTV.DecMapInt32Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Uint8V(rv2i(rv).(map[int32]uint8), false, d)
+		v := rv.Interface().(map[int32]uint8)
+		fastpathTV.DecMapInt32Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Uint8X(vp *map[int32]uint8, d *Decoder) {
-	v, changed := f.DecMapInt32Uint8V(*vp, true, d)
+func (f fastpathT) DecMapInt32Uint8X(vp *map[int32]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, canChange bool,
+func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[int32]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint16)
-		v, changed := fastpathTV.DecMapInt32Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]uint16)
+		v, changed := fastpathTV.DecMapInt32Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Uint16V(rv2i(rv).(map[int32]uint16), false, d)
+		v := rv.Interface().(map[int32]uint16)
+		fastpathTV.DecMapInt32Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Uint16X(vp *map[int32]uint16, d *Decoder) {
-	v, changed := f.DecMapInt32Uint16V(*vp, true, d)
+func (f fastpathT) DecMapInt32Uint16X(vp *map[int32]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, canChange bool,
+func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[int32]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint32)
-		v, changed := fastpathTV.DecMapInt32Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]uint32)
+		v, changed := fastpathTV.DecMapInt32Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Uint32V(rv2i(rv).(map[int32]uint32), false, d)
+		v := rv.Interface().(map[int32]uint32)
+		fastpathTV.DecMapInt32Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Uint32X(vp *map[int32]uint32, d *Decoder) {
-	v, changed := f.DecMapInt32Uint32V(*vp, true, d)
+func (f fastpathT) DecMapInt32Uint32X(vp *map[int32]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, canChange bool,
+func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[int32]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint64)
-		v, changed := fastpathTV.DecMapInt32Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]uint64)
+		v, changed := fastpathTV.DecMapInt32Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Uint64V(rv2i(rv).(map[int32]uint64), false, d)
+		v := rv.Interface().(map[int32]uint64)
+		fastpathTV.DecMapInt32Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Uint64X(vp *map[int32]uint64, d *Decoder) {
-	v, changed := f.DecMapInt32Uint64V(*vp, true, d)
+func (f fastpathT) DecMapInt32Uint64X(vp *map[int32]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, canChange bool,
+func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int32]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uintptr)
-		v, changed := fastpathTV.DecMapInt32UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]uintptr)
+		v, changed := fastpathTV.DecMapInt32UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32UintptrV(rv2i(rv).(map[int32]uintptr), false, d)
+		v := rv.Interface().(map[int32]uintptr)
+		fastpathTV.DecMapInt32UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32UintptrX(vp *map[int32]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt32UintptrV(*vp, true, d)
+func (f fastpathT) DecMapInt32UintptrX(vp *map[int32]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32UintptrV(v map[int32]uintptr, canChange bool,
+func (_ fastpathT) DecMapInt32UintptrV(v map[int32]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int32]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int)
-		v, changed := fastpathTV.DecMapInt32IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]int)
+		v, changed := fastpathTV.DecMapInt32IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32IntV(rv2i(rv).(map[int32]int), false, d)
+		v := rv.Interface().(map[int32]int)
+		fastpathTV.DecMapInt32IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32IntX(vp *map[int32]int, d *Decoder) {
-	v, changed := f.DecMapInt32IntV(*vp, true, d)
+func (f fastpathT) DecMapInt32IntX(vp *map[int32]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32IntV(v map[int32]int, canChange bool,
+func (_ fastpathT) DecMapInt32IntV(v map[int32]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int32]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int8)
-		v, changed := fastpathTV.DecMapInt32Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]int8)
+		v, changed := fastpathTV.DecMapInt32Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Int8V(rv2i(rv).(map[int32]int8), false, d)
+		v := rv.Interface().(map[int32]int8)
+		fastpathTV.DecMapInt32Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Int8X(vp *map[int32]int8, d *Decoder) {
-	v, changed := f.DecMapInt32Int8V(*vp, true, d)
+func (f fastpathT) DecMapInt32Int8X(vp *map[int32]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, canChange bool,
+func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[int32]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int16)
-		v, changed := fastpathTV.DecMapInt32Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]int16)
+		v, changed := fastpathTV.DecMapInt32Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Int16V(rv2i(rv).(map[int32]int16), false, d)
+		v := rv.Interface().(map[int32]int16)
+		fastpathTV.DecMapInt32Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Int16X(vp *map[int32]int16, d *Decoder) {
-	v, changed := f.DecMapInt32Int16V(*vp, true, d)
+func (f fastpathT) DecMapInt32Int16X(vp *map[int32]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, canChange bool,
+func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6)
 		v = make(map[int32]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int32)
-		v, changed := fastpathTV.DecMapInt32Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]int32)
+		v, changed := fastpathTV.DecMapInt32Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Int32V(rv2i(rv).(map[int32]int32), false, d)
+		v := rv.Interface().(map[int32]int32)
+		fastpathTV.DecMapInt32Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Int32X(vp *map[int32]int32, d *Decoder) {
-	v, changed := f.DecMapInt32Int32V(*vp, true, d)
+func (f fastpathT) DecMapInt32Int32X(vp *map[int32]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, canChange bool,
+func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[int32]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int64)
-		v, changed := fastpathTV.DecMapInt32Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]int64)
+		v, changed := fastpathTV.DecMapInt32Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Int64V(rv2i(rv).(map[int32]int64), false, d)
+		v := rv.Interface().(map[int32]int64)
+		fastpathTV.DecMapInt32Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Int64X(vp *map[int32]int64, d *Decoder) {
-	v, changed := f.DecMapInt32Int64V(*vp, true, d)
+func (f fastpathT) DecMapInt32Int64X(vp *map[int32]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, canChange bool,
+func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int32]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]float32)
-		v, changed := fastpathTV.DecMapInt32Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]float32)
+		v, changed := fastpathTV.DecMapInt32Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Float32V(rv2i(rv).(map[int32]float32), false, d)
+		v := rv.Interface().(map[int32]float32)
+		fastpathTV.DecMapInt32Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Float32X(vp *map[int32]float32, d *Decoder) {
-	v, changed := f.DecMapInt32Float32V(*vp, true, d)
+func (f fastpathT) DecMapInt32Float32X(vp *map[int32]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, canChange bool,
+func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8)
 		v = make(map[int32]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]float64)
-		v, changed := fastpathTV.DecMapInt32Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]float64)
+		v, changed := fastpathTV.DecMapInt32Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32Float64V(rv2i(rv).(map[int32]float64), false, d)
+		v := rv.Interface().(map[int32]float64)
+		fastpathTV.DecMapInt32Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32Float64X(vp *map[int32]float64, d *Decoder) {
-	v, changed := f.DecMapInt32Float64V(*vp, true, d)
+func (f fastpathT) DecMapInt32Float64X(vp *map[int32]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, canChange bool,
+func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int32]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt32BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]bool)
-		v, changed := fastpathTV.DecMapInt32BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt32BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int32]bool)
+		v, changed := fastpathTV.DecMapInt32BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt32BoolV(rv2i(rv).(map[int32]bool), false, d)
+		v := rv.Interface().(map[int32]bool)
+		fastpathTV.DecMapInt32BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt32BoolX(vp *map[int32]bool, d *Decoder) {
-	v, changed := f.DecMapInt32BoolV(*vp, true, d)
+func (f fastpathT) DecMapInt32BoolX(vp *map[int32]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt32BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, canChange bool,
+func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int32]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[int32]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int32
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = int32(dd.DecodeInt(32))
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]interface{})
-		v, changed := fastpathTV.DecMapInt64IntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64IntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]interface{})
+		v, changed := fastpathTV.DecMapInt64IntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64IntfV(rv2i(rv).(map[int64]interface{}), false, d)
+		v := rv.Interface().(map[int64]interface{})
+		fastpathTV.DecMapInt64IntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64IntfX(vp *map[int64]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt64IntfV(*vp, true, d)
+func (f fastpathT) DecMapInt64IntfX(vp *map[int64]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64IntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, canChange bool,
+func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[int64]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk int64
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]string)
-		v, changed := fastpathTV.DecMapInt64StringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64StringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]string)
+		v, changed := fastpathTV.DecMapInt64StringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64StringV(rv2i(rv).(map[int64]string), false, d)
+		v := rv.Interface().(map[int64]string)
+		fastpathTV.DecMapInt64StringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64StringX(vp *map[int64]string, d *Decoder) {
-	v, changed := f.DecMapInt64StringV(*vp, true, d)
+func (f fastpathT) DecMapInt64StringX(vp *map[int64]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64StringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64StringV(v map[int64]string, canChange bool,
+func (_ fastpathT) DecMapInt64StringV(v map[int64]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24)
 		v = make(map[int64]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint)
-		v, changed := fastpathTV.DecMapInt64UintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64UintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]uint)
+		v, changed := fastpathTV.DecMapInt64UintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64UintV(rv2i(rv).(map[int64]uint), false, d)
+		v := rv.Interface().(map[int64]uint)
+		fastpathTV.DecMapInt64UintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64UintX(vp *map[int64]uint, d *Decoder) {
-	v, changed := f.DecMapInt64UintV(*vp, true, d)
+func (f fastpathT) DecMapInt64UintX(vp *map[int64]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64UintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, canChange bool,
+func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int64]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint8)
-		v, changed := fastpathTV.DecMapInt64Uint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Uint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]uint8)
+		v, changed := fastpathTV.DecMapInt64Uint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Uint8V(rv2i(rv).(map[int64]uint8), false, d)
+		v := rv.Interface().(map[int64]uint8)
+		fastpathTV.DecMapInt64Uint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Uint8X(vp *map[int64]uint8, d *Decoder) {
-	v, changed := f.DecMapInt64Uint8V(*vp, true, d)
+func (f fastpathT) DecMapInt64Uint8X(vp *map[int64]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Uint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, canChange bool,
+func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int64]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint16)
-		v, changed := fastpathTV.DecMapInt64Uint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Uint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]uint16)
+		v, changed := fastpathTV.DecMapInt64Uint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Uint16V(rv2i(rv).(map[int64]uint16), false, d)
+		v := rv.Interface().(map[int64]uint16)
+		fastpathTV.DecMapInt64Uint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Uint16X(vp *map[int64]uint16, d *Decoder) {
-	v, changed := f.DecMapInt64Uint16V(*vp, true, d)
+func (f fastpathT) DecMapInt64Uint16X(vp *map[int64]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Uint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, canChange bool,
+func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int64]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint32)
-		v, changed := fastpathTV.DecMapInt64Uint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Uint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]uint32)
+		v, changed := fastpathTV.DecMapInt64Uint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Uint32V(rv2i(rv).(map[int64]uint32), false, d)
+		v := rv.Interface().(map[int64]uint32)
+		fastpathTV.DecMapInt64Uint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Uint32X(vp *map[int64]uint32, d *Decoder) {
-	v, changed := f.DecMapInt64Uint32V(*vp, true, d)
+func (f fastpathT) DecMapInt64Uint32X(vp *map[int64]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Uint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, canChange bool,
+func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int64]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint64)
-		v, changed := fastpathTV.DecMapInt64Uint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Uint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]uint64)
+		v, changed := fastpathTV.DecMapInt64Uint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Uint64V(rv2i(rv).(map[int64]uint64), false, d)
+		v := rv.Interface().(map[int64]uint64)
+		fastpathTV.DecMapInt64Uint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Uint64X(vp *map[int64]uint64, d *Decoder) {
-	v, changed := f.DecMapInt64Uint64V(*vp, true, d)
+func (f fastpathT) DecMapInt64Uint64X(vp *map[int64]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Uint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, canChange bool,
+func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int64]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uintptr)
-		v, changed := fastpathTV.DecMapInt64UintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64UintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]uintptr)
+		v, changed := fastpathTV.DecMapInt64UintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64UintptrV(rv2i(rv).(map[int64]uintptr), false, d)
+		v := rv.Interface().(map[int64]uintptr)
+		fastpathTV.DecMapInt64UintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64UintptrX(vp *map[int64]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt64UintptrV(*vp, true, d)
+func (f fastpathT) DecMapInt64UintptrX(vp *map[int64]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64UintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64UintptrV(v map[int64]uintptr, canChange bool,
+func (_ fastpathT) DecMapInt64UintptrV(v map[int64]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int64]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int)
-		v, changed := fastpathTV.DecMapInt64IntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64IntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]int)
+		v, changed := fastpathTV.DecMapInt64IntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64IntV(rv2i(rv).(map[int64]int), false, d)
+		v := rv.Interface().(map[int64]int)
+		fastpathTV.DecMapInt64IntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64IntX(vp *map[int64]int, d *Decoder) {
-	v, changed := f.DecMapInt64IntV(*vp, true, d)
+func (f fastpathT) DecMapInt64IntX(vp *map[int64]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64IntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64IntV(v map[int64]int, canChange bool,
+func (_ fastpathT) DecMapInt64IntV(v map[int64]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int64]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int8)
-		v, changed := fastpathTV.DecMapInt64Int8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Int8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]int8)
+		v, changed := fastpathTV.DecMapInt64Int8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Int8V(rv2i(rv).(map[int64]int8), false, d)
+		v := rv.Interface().(map[int64]int8)
+		fastpathTV.DecMapInt64Int8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Int8X(vp *map[int64]int8, d *Decoder) {
-	v, changed := f.DecMapInt64Int8V(*vp, true, d)
+func (f fastpathT) DecMapInt64Int8X(vp *map[int64]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Int8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, canChange bool,
+func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int64]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int16)
-		v, changed := fastpathTV.DecMapInt64Int16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Int16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]int16)
+		v, changed := fastpathTV.DecMapInt64Int16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Int16V(rv2i(rv).(map[int64]int16), false, d)
+		v := rv.Interface().(map[int64]int16)
+		fastpathTV.DecMapInt64Int16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Int16X(vp *map[int64]int16, d *Decoder) {
-	v, changed := f.DecMapInt64Int16V(*vp, true, d)
+func (f fastpathT) DecMapInt64Int16X(vp *map[int64]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Int16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, canChange bool,
+func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10)
 		v = make(map[int64]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int32)
-		v, changed := fastpathTV.DecMapInt64Int32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Int32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]int32)
+		v, changed := fastpathTV.DecMapInt64Int32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Int32V(rv2i(rv).(map[int64]int32), false, d)
+		v := rv.Interface().(map[int64]int32)
+		fastpathTV.DecMapInt64Int32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Int32X(vp *map[int64]int32, d *Decoder) {
-	v, changed := f.DecMapInt64Int32V(*vp, true, d)
+func (f fastpathT) DecMapInt64Int32X(vp *map[int64]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Int32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, canChange bool,
+func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int64]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int64)
-		v, changed := fastpathTV.DecMapInt64Int64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Int64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]int64)
+		v, changed := fastpathTV.DecMapInt64Int64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Int64V(rv2i(rv).(map[int64]int64), false, d)
+		v := rv.Interface().(map[int64]int64)
+		fastpathTV.DecMapInt64Int64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Int64X(vp *map[int64]int64, d *Decoder) {
-	v, changed := f.DecMapInt64Int64V(*vp, true, d)
+func (f fastpathT) DecMapInt64Int64X(vp *map[int64]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Int64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, canChange bool,
+func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int64]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]float32)
-		v, changed := fastpathTV.DecMapInt64Float32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Float32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]float32)
+		v, changed := fastpathTV.DecMapInt64Float32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Float32V(rv2i(rv).(map[int64]float32), false, d)
+		v := rv.Interface().(map[int64]float32)
+		fastpathTV.DecMapInt64Float32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Float32X(vp *map[int64]float32, d *Decoder) {
-	v, changed := f.DecMapInt64Float32V(*vp, true, d)
+func (f fastpathT) DecMapInt64Float32X(vp *map[int64]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Float32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, canChange bool,
+func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12)
 		v = make(map[int64]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]float64)
-		v, changed := fastpathTV.DecMapInt64Float64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64Float64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]float64)
+		v, changed := fastpathTV.DecMapInt64Float64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64Float64V(rv2i(rv).(map[int64]float64), false, d)
+		v := rv.Interface().(map[int64]float64)
+		fastpathTV.DecMapInt64Float64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64Float64X(vp *map[int64]float64, d *Decoder) {
-	v, changed := f.DecMapInt64Float64V(*vp, true, d)
+func (f fastpathT) DecMapInt64Float64X(vp *map[int64]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64Float64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, canChange bool,
+func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16)
 		v = make(map[int64]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapInt64BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]bool)
-		v, changed := fastpathTV.DecMapInt64BoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapInt64BoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[int64]bool)
+		v, changed := fastpathTV.DecMapInt64BoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapInt64BoolV(rv2i(rv).(map[int64]bool), false, d)
+		v := rv.Interface().(map[int64]bool)
+		fastpathTV.DecMapInt64BoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapInt64BoolX(vp *map[int64]bool, d *Decoder) {
-	v, changed := f.DecMapInt64BoolV(*vp, true, d)
+func (f fastpathT) DecMapInt64BoolX(vp *map[int64]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapInt64BoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, canChange bool,
+func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[int64]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[int64]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk int64
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeInt(64)
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]interface{})
-		v, changed := fastpathTV.DecMapBoolIntfV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolIntfR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]interface{})
+		v, changed := fastpathTV.DecMapBoolIntfV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolIntfV(rv2i(rv).(map[bool]interface{}), false, d)
+		v := rv.Interface().(map[bool]interface{})
+		fastpathTV.DecMapBoolIntfV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolIntfX(vp *map[bool]interface{}, d *Decoder) {
-	v, changed := f.DecMapBoolIntfV(*vp, true, d)
+func (f fastpathT) DecMapBoolIntfX(vp *map[bool]interface{}, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolIntfV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, canChange bool,
+func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[bool]interface{}, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	mapGet := !d.h.MapValueReset && !d.h.InterfaceReset
 	var mk bool
 	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
 			} else {
-				v[mk] = nil
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
 		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			if mapGet {
+				mv = v[mk]
+			} else {
+				mv = nil
+			}
+			d.decode(&mv)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]string)
-		v, changed := fastpathTV.DecMapBoolStringV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolStringR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]string)
+		v, changed := fastpathTV.DecMapBoolStringV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolStringV(rv2i(rv).(map[bool]string), false, d)
+		v := rv.Interface().(map[bool]string)
+		fastpathTV.DecMapBoolStringV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolStringX(vp *map[bool]string, d *Decoder) {
-	v, changed := f.DecMapBoolStringV(*vp, true, d)
+func (f fastpathT) DecMapBoolStringX(vp *map[bool]string, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolStringV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolStringV(v map[bool]string, canChange bool,
+func (_ fastpathT) DecMapBoolStringV(v map[bool]string, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17)
 		v = make(map[bool]string, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeString()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint)
-		v, changed := fastpathTV.DecMapBoolUintV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolUintR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]uint)
+		v, changed := fastpathTV.DecMapBoolUintV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolUintV(rv2i(rv).(map[bool]uint), false, d)
+		v := rv.Interface().(map[bool]uint)
+		fastpathTV.DecMapBoolUintV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolUintX(vp *map[bool]uint, d *Decoder) {
-	v, changed := f.DecMapBoolUintV(*vp, true, d)
+func (f fastpathT) DecMapBoolUintX(vp *map[bool]uint, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolUintV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, canChange bool,
+func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[bool]uint, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint8)
-		v, changed := fastpathTV.DecMapBoolUint8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolUint8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]uint8)
+		v, changed := fastpathTV.DecMapBoolUint8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolUint8V(rv2i(rv).(map[bool]uint8), false, d)
+		v := rv.Interface().(map[bool]uint8)
+		fastpathTV.DecMapBoolUint8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolUint8X(vp *map[bool]uint8, d *Decoder) {
-	v, changed := f.DecMapBoolUint8V(*vp, true, d)
+func (f fastpathT) DecMapBoolUint8X(vp *map[bool]uint8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolUint8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, canChange bool,
+func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[bool]uint8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint8(dd.DecodeUint(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint16)
-		v, changed := fastpathTV.DecMapBoolUint16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolUint16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]uint16)
+		v, changed := fastpathTV.DecMapBoolUint16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolUint16V(rv2i(rv).(map[bool]uint16), false, d)
+		v := rv.Interface().(map[bool]uint16)
+		fastpathTV.DecMapBoolUint16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolUint16X(vp *map[bool]uint16, d *Decoder) {
-	v, changed := f.DecMapBoolUint16V(*vp, true, d)
+func (f fastpathT) DecMapBoolUint16X(vp *map[bool]uint16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolUint16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, canChange bool,
+func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[bool]uint16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint16(dd.DecodeUint(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint32)
-		v, changed := fastpathTV.DecMapBoolUint32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolUint32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]uint32)
+		v, changed := fastpathTV.DecMapBoolUint32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolUint32V(rv2i(rv).(map[bool]uint32), false, d)
+		v := rv.Interface().(map[bool]uint32)
+		fastpathTV.DecMapBoolUint32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolUint32X(vp *map[bool]uint32, d *Decoder) {
-	v, changed := f.DecMapBoolUint32V(*vp, true, d)
+func (f fastpathT) DecMapBoolUint32X(vp *map[bool]uint32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolUint32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, canChange bool,
+func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[bool]uint32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uint32(dd.DecodeUint(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint64)
-		v, changed := fastpathTV.DecMapBoolUint64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolUint64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]uint64)
+		v, changed := fastpathTV.DecMapBoolUint64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolUint64V(rv2i(rv).(map[bool]uint64), false, d)
+		v := rv.Interface().(map[bool]uint64)
+		fastpathTV.DecMapBoolUint64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolUint64X(vp *map[bool]uint64, d *Decoder) {
-	v, changed := f.DecMapBoolUint64V(*vp, true, d)
+func (f fastpathT) DecMapBoolUint64X(vp *map[bool]uint64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolUint64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, canChange bool,
+func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[bool]uint64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeUint(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uintptr)
-		v, changed := fastpathTV.DecMapBoolUintptrV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolUintptrR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]uintptr)
+		v, changed := fastpathTV.DecMapBoolUintptrV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolUintptrV(rv2i(rv).(map[bool]uintptr), false, d)
+		v := rv.Interface().(map[bool]uintptr)
+		fastpathTV.DecMapBoolUintptrV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolUintptrX(vp *map[bool]uintptr, d *Decoder) {
-	v, changed := f.DecMapBoolUintptrV(*vp, true, d)
+func (f fastpathT) DecMapBoolUintptrX(vp *map[bool]uintptr, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolUintptrV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolUintptrV(v map[bool]uintptr, canChange bool,
+func (_ fastpathT) DecMapBoolUintptrV(v map[bool]uintptr, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[bool]uintptr, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = uintptr(dd.DecodeUint(uintBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int)
-		v, changed := fastpathTV.DecMapBoolIntV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolIntR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]int)
+		v, changed := fastpathTV.DecMapBoolIntV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolIntV(rv2i(rv).(map[bool]int), false, d)
+		v := rv.Interface().(map[bool]int)
+		fastpathTV.DecMapBoolIntV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolIntX(vp *map[bool]int, d *Decoder) {
-	v, changed := f.DecMapBoolIntV(*vp, true, d)
+func (f fastpathT) DecMapBoolIntX(vp *map[bool]int, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolIntV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolIntV(v map[bool]int, canChange bool,
+func (_ fastpathT) DecMapBoolIntV(v map[bool]int, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[bool]int, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int(dd.DecodeInt(intBitsize))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int8)
-		v, changed := fastpathTV.DecMapBoolInt8V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolInt8R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]int8)
+		v, changed := fastpathTV.DecMapBoolInt8V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolInt8V(rv2i(rv).(map[bool]int8), false, d)
+		v := rv.Interface().(map[bool]int8)
+		fastpathTV.DecMapBoolInt8V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolInt8X(vp *map[bool]int8, d *Decoder) {
-	v, changed := f.DecMapBoolInt8V(*vp, true, d)
+func (f fastpathT) DecMapBoolInt8X(vp *map[bool]int8, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolInt8V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, canChange bool,
+func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[bool]int8, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int8(dd.DecodeInt(8))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int16)
-		v, changed := fastpathTV.DecMapBoolInt16V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolInt16R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]int16)
+		v, changed := fastpathTV.DecMapBoolInt16V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolInt16V(rv2i(rv).(map[bool]int16), false, d)
+		v := rv.Interface().(map[bool]int16)
+		fastpathTV.DecMapBoolInt16V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolInt16X(vp *map[bool]int16, d *Decoder) {
-	v, changed := f.DecMapBoolInt16V(*vp, true, d)
+func (f fastpathT) DecMapBoolInt16X(vp *map[bool]int16, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolInt16V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, canChange bool,
+func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3)
 		v = make(map[bool]int16, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int16(dd.DecodeInt(16))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int32)
-		v, changed := fastpathTV.DecMapBoolInt32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolInt32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]int32)
+		v, changed := fastpathTV.DecMapBoolInt32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolInt32V(rv2i(rv).(map[bool]int32), false, d)
+		v := rv.Interface().(map[bool]int32)
+		fastpathTV.DecMapBoolInt32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolInt32X(vp *map[bool]int32, d *Decoder) {
-	v, changed := f.DecMapBoolInt32V(*vp, true, d)
+func (f fastpathT) DecMapBoolInt32X(vp *map[bool]int32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolInt32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, canChange bool,
+func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[bool]int32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = int32(dd.DecodeInt(32))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int64)
-		v, changed := fastpathTV.DecMapBoolInt64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolInt64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]int64)
+		v, changed := fastpathTV.DecMapBoolInt64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolInt64V(rv2i(rv).(map[bool]int64), false, d)
+		v := rv.Interface().(map[bool]int64)
+		fastpathTV.DecMapBoolInt64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolInt64X(vp *map[bool]int64, d *Decoder) {
-	v, changed := f.DecMapBoolInt64V(*vp, true, d)
+func (f fastpathT) DecMapBoolInt64X(vp *map[bool]int64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolInt64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, canChange bool,
+func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[bool]int64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeInt(64)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]float32)
-		v, changed := fastpathTV.DecMapBoolFloat32V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolFloat32R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]float32)
+		v, changed := fastpathTV.DecMapBoolFloat32V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolFloat32V(rv2i(rv).(map[bool]float32), false, d)
+		v := rv.Interface().(map[bool]float32)
+		fastpathTV.DecMapBoolFloat32V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolFloat32X(vp *map[bool]float32, d *Decoder) {
-	v, changed := f.DecMapBoolFloat32V(*vp, true, d)
+func (f fastpathT) DecMapBoolFloat32X(vp *map[bool]float32, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolFloat32V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, canChange bool,
+func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5)
 		v = make(map[bool]float32, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = float32(dd.DecodeFloat(true))
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]float64)
-		v, changed := fastpathTV.DecMapBoolFloat64V(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolFloat64R(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]float64)
+		v, changed := fastpathTV.DecMapBoolFloat64V(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolFloat64V(rv2i(rv).(map[bool]float64), false, d)
+		v := rv.Interface().(map[bool]float64)
+		fastpathTV.DecMapBoolFloat64V(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolFloat64X(vp *map[bool]float64, d *Decoder) {
-	v, changed := f.DecMapBoolFloat64V(*vp, true, d)
+func (f fastpathT) DecMapBoolFloat64X(vp *map[bool]float64, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolFloat64V(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, canChange bool,
+func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9)
 		v = make(map[bool]float64, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeFloat(false)
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
 
-func (d *Decoder) fastpathDecMapBoolBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]bool)
-		v, changed := fastpathTV.DecMapBoolBoolV(*vp, true, d)
+func (f *decFnInfo) fastpathDecMapBoolBoolR(rv reflect.Value) {
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[bool]bool)
+		v, changed := fastpathTV.DecMapBoolBoolV(*vp, fastpathCheckNilFalse, true, f.d)
 		if changed {
 			*vp = v
 		}
 	} else {
-		fastpathTV.DecMapBoolBoolV(rv2i(rv).(map[bool]bool), false, d)
+		v := rv.Interface().(map[bool]bool)
+		fastpathTV.DecMapBoolBoolV(v, fastpathCheckNilFalse, false, f.d)
 	}
 }
-func (f fastpathT) DecMapBoolBoolX(vp *map[bool]bool, d *Decoder) {
-	v, changed := f.DecMapBoolBoolV(*vp, true, d)
+func (f fastpathT) DecMapBoolBoolX(vp *map[bool]bool, checkNil bool, d *Decoder) {
+	v, changed := f.DecMapBoolBoolV(*vp, checkNil, true, d)
 	if changed {
 		*vp = v
 	}
 }
-func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, canChange bool,
+func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, checkNil bool, canChange bool,
 	d *Decoder) (_ map[bool]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
+	dd := d.d
+	cr := d.cr
+
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		}
+		return nil, changed
+	}
+
 	containerLen := dd.ReadMapStart()
 	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2)
 		v = make(map[bool]bool, xlen)
 		changed = true
 	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
+
 	var mk bool
 	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
 			}
-			continue
 		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil {
+				cr.sendContainerState(containerMapKey)
+			}
+			mk = dd.DecodeBool()
+			if cr != nil {
+				cr.sendContainerState(containerMapValue)
+			}
+			mv = dd.DecodeBool()
+			if v != nil {
+				v[mk] = mv
+			}
 		}
 	}
-	dd.ReadMapEnd()
+	if cr != nil {
+		cr.sendContainerState(containerMapEnd)
+	}
 	return v, changed
 }
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl b/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
new file mode 100644
index 000000000..c3ffdf93d
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
@@ -0,0 +1,527 @@
+// +build !notfastpath
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// ************************************************************
+// DO NOT EDIT. 
+// THIS FILE IS AUTO-GENERATED from fast-path.go.tmpl
+// ************************************************************
+
+package codec
+
+// Fast path functions try to create a fast path encode or decode implementation
+// for common maps and slices.
+//
+// We define the functions and register then in this single file
+// so as not to pollute the encode.go and decode.go, and create a dependency in there.
+// This file can be omitted without causing a build failure.
+//
+// The advantage of fast paths is:
+//    - Many calls bypass reflection altogether
+// 
+// Currently support
+//    - slice of all builtin types,
+//    - map of all builtin types to string or interface value
+//    - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
+// This should provide adequate "typical" implementations.
+// 
+// Note that fast track decode functions must handle values for which an address cannot be obtained.
+// For example: 
+//   m2 := map[string]int{}
+//   p2 := []interface{}{m2}
+//   // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
+// 
+
+import (
+	"reflect"
+	"sort"
+)
+
+const fastpathEnabled = true
+
+const fastpathCheckNilFalse = false // for reflect
+const fastpathCheckNilTrue = true // for type switch
+
+type fastpathT struct {}
+
+var fastpathTV fastpathT
+
+type fastpathE struct {
+	rtid uintptr
+	rt reflect.Type 
+	encfn func(*encFnInfo, reflect.Value)
+	decfn func(*decFnInfo, reflect.Value)
+}
+
+type fastpathA [{{ .FastpathLen }}]fastpathE
+
+func (x *fastpathA) index(rtid uintptr) int {
+	// use binary search to grab the index (adapted from sort/search.go)
+	h, i, j := 0, 0, {{ .FastpathLen }} // len(x)
+	for i < j {
+		h = i + (j-i)/2
+		if x[h].rtid < rtid {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	if i < {{ .FastpathLen }} && x[i].rtid == rtid {
+		return i
+	}
+	return -1
+}
+
+type fastpathAslice []fastpathE
+
+func (x fastpathAslice) Len() int { return len(x) }
+func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
+func (x fastpathAslice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+var fastpathAV fastpathA
+
+// due to possible initialization loop error, make fastpath in an init()
+func init() {
+	i := 0
+	fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) {
+		xrt := reflect.TypeOf(v)
+		xptr := reflect.ValueOf(xrt).Pointer()
+		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
+		i++
+		return
+	}
+	
+	{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+	fn([]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
+	
+	{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+	fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
+	
+	sort.Sort(fastpathAslice(fastpathAV[:]))
+}
+
+// -- encode
+
+// -- -- fast path type switch
+func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+	case []{{ .Elem }}:{{else}}
+	case map[{{ .MapKey }}]{{ .Elem }}:{{end}}
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e){{if not .MapKey }}
+	case *[]{{ .Elem }}:{{else}}
+	case *map[{{ .MapKey }}]{{ .Elem }}:{{end}}
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e)
+{{end}}{{end}}
+	default:
+        _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
+		return false
+	}
+	return true
+}
+
+func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+	case []{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e)
+	case *[]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e)
+{{end}}{{end}}{{end}}
+	default:
+        _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
+		return false
+	}
+	return true
+}
+
+func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+	case map[{{ .MapKey }}]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e)
+	case *map[{{ .MapKey }}]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e)
+{{end}}{{end}}{{end}}
+	default:
+        _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
+		return false
+	}
+	return true
+}
+
+// -- -- fast path functions
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} 
+
+func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e)
+	} else {
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e)
+	}
+}
+func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeArrayStart(len(v))
+	for _, v2 := range v {
+		if cr != nil { cr.sendContainerState(containerArrayElem) }
+		{{ encmd .Elem "v2"}}
+	}
+	if cr != nil { cr.sendContainerState(containerArrayEnd) }{{/* ee.EncodeEnd() */}}
+}
+
+func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.EncodeMapStart(len(v) / 2)
+	for j, v2 := range v {
+		if cr != nil {
+			if j%2 == 0 {
+				cr.sendContainerState(containerMapKey)
+			} else {
+				cr.sendContainerState(containerMapValue)
+			}
+		}
+		{{ encmd .Elem "v2"}}
+	}
+	if cr != nil { cr.sendContainerState(containerMapEnd) }
+}
+
+{{end}}{{end}}{{end}}
+
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+
+func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) {
+	fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().(map[{{ .MapKey }}]{{ .Elem }}), fastpathCheckNilFalse, f.e)
+}
+func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, e *Encoder) {
+	ee := e.e
+	cr := e.cr
+	if checkNil && v == nil {
+		ee.EncodeNil()
+		return
+	}
+	ee.EncodeMapStart(len(v))
+	{{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
+	{{end}}if e.h.Canonical {
+		{{if eq .MapKey "interface{}"}}{{/* out of band 
+		*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}}
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2 
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		for j := range v2 {
+			if cr != nil { cr.sendContainerState(containerMapKey) }
+			e.asis(v2[j].v)
+			if cr != nil { cr.sendContainerState(containerMapValue) }
+			e.encode(v[v2[j].i])
+		} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
+		var i int 
+		for k, _ := range v {
+			v2[i] = {{ $x }}(k)
+			i++
+		}
+		sort.Sort({{ sorttype .MapKey false}}(v2))
+		for _, k2 := range v2 {
+			if cr != nil { cr.sendContainerState(containerMapKey) }
+			{{if eq .MapKey "string"}}if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}{{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
+			if cr != nil { cr.sendContainerState(containerMapValue) }
+			{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
+		} {{end}}
+	} else {
+		for k2, v2 := range v {
+			if cr != nil { cr.sendContainerState(containerMapKey) }
+			{{if eq .MapKey "string"}}if asSymbols {
+				ee.EncodeSymbol(k2)
+			} else {
+				ee.EncodeString(c_UTF8, k2)
+			}{{else}}{{ encmd .MapKey "k2"}}{{end}}
+			if cr != nil { cr.sendContainerState(containerMapValue) }
+			{{ encmd .Elem "v2"}}
+		}
+	}
+	if cr != nil { cr.sendContainerState(containerMapEnd) }{{/* ee.EncodeEnd() */}}
+}
+
+{{end}}{{end}}{{end}}
+
+// -- decode
+
+// -- -- fast path type switch
+func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+	case []{{ .Elem }}:{{else}}
+	case map[{{ .MapKey }}]{{ .Elem }}:{{end}}
+		fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, d){{if not .MapKey }}
+	case *[]{{ .Elem }}:{{else}}
+	case *map[{{ .MapKey }}]{{ .Elem }}:{{end}}
+		v2, changed2 := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, fastpathCheckNilFalse, true, d)
+		if changed2 {
+			*v = v2 
+		}
+{{end}}{{end}}
+	default:
+        _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
+		return false
+	}
+	return true
+}
+
+// -- -- fast path functions
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+{{/*
+Slices can change if they 
+- did not come from an array
+- are addressable (from a ptr)
+- are settable (e.g. contained in an interface{})
+*/}}
+func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { 
+	array := f.seq == seqTypeArray
+	if !array && rv.CanAddr() { {{/* // CanSet => CanAddr + Exported */}}
+		vp := rv.Addr().Interface().(*[]{{ .Elem }})
+		v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, !array, f.d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv.Interface().([]{{ .Elem }})
+		fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, f.d)
+	}
+}
+
+func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, checkNil bool, d *Decoder) {
+	v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, checkNil, true, d)
+	if changed {
+		*vp = v 
+	}
+}
+func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil bool, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
+	dd := d.d
+	{{/* // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() */}}
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true 
+		}
+		return nil, changed 
+	}
+
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []{{ .Elem }}{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	
+	if containerLenS > 0 {
+		x2read := containerLenS
+		var xtrunc bool 
+		if containerLenS > cap(v) {
+			if canChange { {{/*
+				// fast-path is for "basic" immutable types, so no need to copy them over
+				// s := make([]{{ .Elem }}, decInferLen(containerLenS, d.h.MaxInitLen))
+				// copy(s, v[:cap(v)])
+				// v = s */}}
+				var xlen int 
+                xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
+				if xtrunc {
+					if xlen <= cap(v) {
+						v = v[:xlen]
+					} else {
+						v = make([]{{ .Elem }}, xlen)
+					}
+				} else {
+					v = make([]{{ .Elem }}, xlen)
+				}
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), containerLenS)
+			}
+			x2read = len(v)
+		} else if containerLenS != len(v) {
+			if canChange {
+				v = v[:containerLenS]
+				changed = true
+			}
+		} {{/* // all checks done. cannot go past len. */}}
+		j := 0
+		for ; j < x2read; j++ {
+			slh.ElemContainerState(j)
+			{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
+		}
+		if xtrunc { {{/* // means canChange=true, changed=true already. */}}
+			for ; j < containerLenS; j++ {
+				v = append(v, {{ zerocmd .Elem }})
+				slh.ElemContainerState(j)
+				{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
+			}
+		} else if !canChange {
+			for ; j < containerLenS; j++ {
+				slh.ElemContainerState(j)
+				d.swallow()
+			}
+		}
+	} else {
+		breakFound := dd.CheckBreak() {{/* check break first, so we can initialize v with a capacity of 4 if necessary */}}
+		if breakFound {
+			if canChange {
+				if v == nil {
+					v = []{{ .Elem }}{}
+				} else if len(v) != 0 {
+					v = v[:0]
+				}
+				changed = true
+			}
+			slh.End()
+			return v, changed
+		}
+		if cap(v) == 0 {
+			v = make([]{{ .Elem }}, 1, 4)
+			changed = true
+		}
+		j := 0	
+		for ; !breakFound; j++ {
+			if j >= len(v) { 
+				if canChange {
+					v = append(v, {{ zerocmd .Elem }})
+					changed = true
+				} else {
+					d.arrayCannotExpand(len(v), j+1)
+				}
+			}
+			slh.ElemContainerState(j)
+			if j < len(v) { {{/* // all checks done. cannot go past len. */}}
+				{{ if eq .Elem "interface{}" }}d.decode(&v[j])
+				{{ else }}v[j] = {{ decmd .Elem }}{{ end }}
+			} else {
+				d.swallow()
+			}
+			breakFound = dd.CheckBreak()
+		}
+		if canChange && j < len(v) {
+			v = v[:j]
+			changed = true
+		}
+	}
+	slh.End() 
+	return v, changed 
+}
+
+{{end}}{{end}}{{end}}
+
+
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+{{/*
+Maps can change if they are
+- addressable (from a ptr)
+- settable (e.g. contained in an interface{})
+*/}}
+func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { 
+	if rv.CanAddr() {
+		vp := rv.Addr().Interface().(*map[{{ .MapKey }}]{{ .Elem }})
+		v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, true, f.d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv.Interface().(map[{{ .MapKey }}]{{ .Elem }})
+		fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, f.d)
+	}
+}
+func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, d *Decoder) {
+	v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, checkNil, true, d)
+	if changed {
+		*vp = v 
+	}
+}
+func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, canChange bool, 
+	d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
+	dd := d.d
+	cr := d.cr
+	{{/* // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() */}}
+	if checkNil && dd.TryDecodeAsNil() {
+		if v != nil {
+			changed = true
+		} 
+		return nil, changed
+	}
+
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
+		v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
+		changed = true
+	}
+	{{ if eq .Elem "interface{}" }}mapGet := !d.h.MapValueReset && !d.h.InterfaceReset{{end}}
+	var mk {{ .MapKey }}
+	var mv {{ .Elem }}
+	if containerLen > 0 {
+		for j := 0; j < containerLen; j++ {
+			if cr != nil { cr.sendContainerState(containerMapKey) }
+			{{ if eq .MapKey "interface{}" }}mk = nil 
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
+			}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
+			if cr != nil { cr.sendContainerState(containerMapValue) }
+			{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
+			d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
+			if v != nil {
+				v[mk] = mv
+			}
+		}
+	} else if containerLen < 0 {
+		for j := 0; !dd.CheckBreak(); j++ {
+			if cr != nil { cr.sendContainerState(containerMapKey) }
+			{{ if eq .MapKey "interface{}" }}mk = nil 
+			d.decode(&mk)
+			if bv, bok := mk.([]byte); bok {
+				mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
+			}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
+			if cr != nil { cr.sendContainerState(containerMapValue) }
+			{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
+			d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
+			if v != nil {
+				v[mk] = mv
+			}
+		}
+	}
+	if cr != nil { cr.sendContainerState(containerMapEnd) }
+	return v, changed
+}
+
+{{end}}{{end}}{{end}}
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.not.go b/vendor/github.com/ugorji/go/codec/fast-path.not.go
index f11b4674f..63e591145 100644
--- a/vendor/github.com/ugorji/go/codec/fast-path.not.go
+++ b/vendor/github.com/ugorji/go/codec/fast-path.not.go
@@ -1,6 +1,3 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
 // +build notfastpath
 
 package codec
@@ -21,27 +18,17 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool      { return fal
 func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool      { return false }
 func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
 func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool   { return false }
-func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool           { return false }
 
 type fastpathT struct{}
 type fastpathE struct {
 	rtid  uintptr
 	rt    reflect.Type
-	encfn func(*Encoder, *codecFnInfo, reflect.Value)
-	decfn func(*Decoder, *codecFnInfo, reflect.Value)
+	encfn func(*encFnInfo, reflect.Value)
+	decfn func(*decFnInfo, reflect.Value)
 }
 type fastpathA [0]fastpathE
 
 func (x fastpathA) index(rtid uintptr) int { return -1 }
 
-func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
-	fn := d.cfer().get(uint8SliceTyp, true, true)
-	d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
-	return v, true
-}
-
 var fastpathAV fastpathA
 var fastpathTV fastpathT
-
-// ----
-type TestMammoth2Wrapper struct{} // to allow testMammoth work in notfastpath mode
diff --git a/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
new file mode 100644
index 000000000..32df54144
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
@@ -0,0 +1,104 @@
+{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
+{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
+var {{var "c"}} bool {{/* // changed */}}
+_ = {{var "c"}}{{end}}
+if {{var "l"}} == 0 {
+	{{if isSlice }}if {{var "v"}} == nil {
+		{{var "v"}} = []{{ .Typ }}{}
+		{{var "c"}} = true
+	} else if len({{var "v"}}) != 0 {
+		{{var "v"}} = {{var "v"}}[:0]
+		{{var "c"}} = true
+	} {{end}} {{if isChan }}if {{var "v"}} == nil {
+		{{var "v"}} = make({{ .CTyp }}, 0)
+		{{var "c"}} = true
+	} {{end}}
+} else if {{var "l"}} > 0 {
+	{{if isChan }}if {{var "v"}} == nil {
+		{{var "rl"}}, _ = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+		{{var "v"}} = make({{ .CTyp }}, {{var "rl"}})
+		{{var "c"}} = true
+	}
+	for {{var "r"}} := 0; {{var "r"}} < {{var "l"}}; {{var "r"}}++ {
+		{{var "h"}}.ElemContainerState({{var "r"}})
+		var {{var "t"}} {{ .Typ }}
+		{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }}
+		{{var "v"}} <- {{var "t"}}
+	}
+	{{ else }}	var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
+	var {{var "rt"}} bool {{/* truncated */}}
+	_, _ = {{var "rl"}}, {{var "rt"}}
+	{{var "rr"}} = {{var "l"}} // len({{var "v"}})
+	if {{var "l"}} > cap({{var "v"}}) {
+		{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
+		{{ else }}{{if not .Immutable }}
+		{{var "rg"}} := len({{var "v"}}) > 0
+		{{var "v2"}} := {{var "v"}} {{end}}
+		{{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+		if {{var "rt"}} {
+			if {{var "rl"}} <= cap({{var "v"}}) {
+				{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
+			} else {
+				{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
+			}
+		} else {
+			{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
+		}
+		{{var "c"}} = true
+		{{var "rr"}} = len({{var "v"}}) {{if not .Immutable }}
+			if {{var "rg"}} { copy({{var "v"}}, {{var "v2"}}) } {{end}} {{end}}{{/* end not Immutable, isArray */}}
+	} {{if isSlice }} else if {{var "l"}} != len({{var "v"}}) {
+		{{var "v"}} = {{var "v"}}[:{{var "l"}}]
+		{{var "c"}} = true
+	} {{end}}	{{/* end isSlice:47 */}} 
+	{{var "j"}} := 0
+	for ; {{var "j"}} < {{var "rr"}} ; {{var "j"}}++ {
+		{{var "h"}}.ElemContainerState({{var "j"}})
+		{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
+	}
+	{{if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ {
+		{{var "h"}}.ElemContainerState({{var "j"}})
+		z.DecSwallow()
+	}
+	{{ else }}if {{var "rt"}} {
+		for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ {
+			{{var "v"}} = append({{var "v"}}, {{ zero}})
+			{{var "h"}}.ElemContainerState({{var "j"}})
+			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
+		}
+	} {{end}} {{/* end isArray:56 */}}
+	{{end}} {{/* end isChan:16 */}}
+} else { {{/* len < 0 */}}
+	{{var "j"}} := 0
+	for ; !r.CheckBreak(); {{var "j"}}++ {
+		{{if isChan }}
+		{{var "h"}}.ElemContainerState({{var "j"}})
+		var {{var "t"}} {{ .Typ }}
+		{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }}
+		{{var "v"}} <- {{var "t"}} 
+		{{ else }}
+		if {{var "j"}} >= len({{var "v"}}) {
+			{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1)
+			{{ else }}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }}
+			{{var "c"}} = true {{end}}
+		}
+		{{var "h"}}.ElemContainerState({{var "j"}})
+		if {{var "j"}} < len({{var "v"}}) {
+			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
+		} else {
+			z.DecSwallow()
+		}
+		{{end}}
+	}
+	{{if isSlice }}if {{var "j"}} < len({{var "v"}}) {
+		{{var "v"}} = {{var "v"}}[:{{var "j"}}]
+		{{var "c"}} = true
+	} else if {{var "j"}} == 0 && {{var "v"}} == nil {
+		{{var "v"}} = []{{ .Typ }}{}
+		{{var "c"}} = true
+	}{{end}}
+}
+{{var "h"}}.End()
+{{if not isArray }}if {{var "c"}} { 
+	*{{ .Varname }} = {{var "v"}}
+}{{end}}
diff --git a/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
new file mode 100644
index 000000000..77400e0a1
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
@@ -0,0 +1,58 @@
+{{var "v"}} := *{{ .Varname }}
+{{var "l"}} := r.ReadMapStart()
+{{var "bh"}} := z.DecBasicHandle()
+if {{var "v"}} == nil {
+	{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
+	{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
+	*{{ .Varname }} = {{var "v"}}
+}
+var {{var "mk"}} {{ .KTyp }}
+var {{var "mv"}} {{ .Typ }}
+var {{var "mg"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
+if {{var "bh"}}.MapValueReset {
+	{{if decElemKindPtr}}{{var "mg"}} = true
+	{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
+	{{else if not decElemKindImmutable}}{{var "mg"}} = true
+	{{end}} }
+if {{var "l"}} > 0  {
+for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ {
+	z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }})
+	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
+{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
+		{{var "mk"}} = string({{var "bv"}})
+	}{{ end }}{{if decElemKindPtr}}
+	{{var "ms"}} = true{{end}}
+	if {{var "mg"}} {
+		{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] 
+		if {{var "mok"}} {
+			{{var "ms"}} = false
+		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
+	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
+	z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }})
+	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
+	if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
+		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
+	}
+}
+} else if {{var "l"}} < 0  {
+for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ {
+	z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }})
+	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
+{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
+		{{var "mk"}} = string({{var "bv"}})
+	}{{ end }}{{if decElemKindPtr}}
+	{{var "ms"}} = true {{ end }}
+	if {{var "mg"}} {
+		{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] 
+		if {{var "mok"}} {
+			{{var "ms"}} = false
+		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
+	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
+	z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }})
+	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
+	if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
+		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
+	}
+}
+} // else len==0: TODO: Should we clear map entries?
+z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }})
diff --git a/vendor/github.com/ugorji/go/codec/gen-helper.generated.go b/vendor/github.com/ugorji/go/codec/gen-helper.generated.go
index 917d28283..eb0bdad35 100644
--- a/vendor/github.com/ugorji/go/codec/gen-helper.generated.go
+++ b/vendor/github.com/ugorji/go/codec/gen-helper.generated.go
@@ -3,7 +3,10 @@
 // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
-// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
+// ************************************************************
+// DO NOT EDIT.
+// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
+// ************************************************************
 
 package codec
 
@@ -12,9 +15,6 @@ import (
 	"reflect"
 )
 
-// GenVersion is the current version of codecgen.
-const GenVersion = 8
-
 // This file is used to generate helper code for codecgen.
 // The values here i.e. genHelper(En|De)coder are not to be used directly by
 // library users. They WILL change continuously and without notice.
@@ -26,75 +26,25 @@ const GenVersion = 8
 // to perform encoding or decoding of primitives or known slice or map types.
 
 // GenHelperEncoder is exported so that it can be used externally by codecgen.
-//
 // Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
-func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
-	ge = genHelperEncoder{e: e}
-	ee = genHelperEncDriver{encDriver: e.e}
-	return
+func GenHelperEncoder(e *Encoder) (genHelperEncoder, encDriver) {
+	return genHelperEncoder{e: e}, e.e
 }
 
 // GenHelperDecoder is exported so that it can be used externally by codecgen.
-//
 // Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
-func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
-	gd = genHelperDecoder{d: d}
-	dd = genHelperDecDriver{decDriver: d.d}
-	return
-}
-
-type genHelperEncDriver struct {
-	encDriver
-}
-
-func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
-func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
-	encStructFieldKey(x.encDriver, keyType, s)
-}
-func (x genHelperEncDriver) EncodeSymbol(s string) {
-	x.encDriver.EncodeString(cUTF8, s)
-}
-
-type genHelperDecDriver struct {
-	decDriver
-	C checkOverflow
-}
-
-func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
-func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
-	return decStructFieldKey(x.decDriver, keyType, buf)
-}
-func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
-	return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
-}
-func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
-	return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
-}
-func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
-	f = x.DecodeFloat64()
-	if chkOverflow32 && chkOvf.Float32(f) {
-		panicv.errorf("float32 overflow: %v", f)
-	}
-	return
-}
-func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
-	f = x.DecodeFloat64()
-	if chkOvf.Float32(f) {
-		panicv.errorf("float32 overflow: %v", f)
-	}
-	return
+func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) {
+	return genHelperDecoder{d: d}, d.d
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 type genHelperEncoder struct {
-	M must
 	e *Encoder
 	F fastpathT
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 type genHelperDecoder struct {
-	C checkOverflow
 	d *Decoder
 	F fastpathT
 }
@@ -109,86 +59,74 @@ func (f genHelperEncoder) EncBinary() bool {
 	return f.e.be // f.e.hh.isBinaryEncoding()
 }
 
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) IsJSONHandle() bool {
-	return f.e.js
-}
-
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperEncoder) EncFallback(iv interface{}) {
 	// println(">>>>>>>>> EncFallback")
-	// f.e.encodeI(iv, false, false)
-	f.e.encodeValue(reflect.ValueOf(iv), nil, false)
+	f.e.encodeI(iv, false, false)
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
 	bs, fnerr := iv.MarshalText()
-	f.e.marshal(bs, fnerr, false, cUTF8)
+	f.e.marshal(bs, fnerr, false, c_UTF8)
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
 	bs, fnerr := iv.MarshalJSON()
-	f.e.marshal(bs, fnerr, true, cUTF8)
+	f.e.marshal(bs, fnerr, true, c_UTF8)
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
 	bs, fnerr := iv.MarshalBinary()
-	f.e.marshal(bs, fnerr, false, cRAW)
+	f.e.marshal(bs, fnerr, false, c_RAW)
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: builtin no longer supported - so we make this method a no-op,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
-
-// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
-// 	if _, ok := f.e.hh.(*BincHandle); ok {
-// 		return timeTypId
-// 	}
-// }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
-	return i2rtid(v)
+func (f genHelperEncoder) EncRaw(iv Raw) {
+	f.e.raw(iv)
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
-	return f.e.h.getExt(rtid)
+func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
+	if _, ok := f.e.hh.(*BincHandle); ok {
+		return timeTypId
+	}
+	return 0
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
-	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
+func (f genHelperEncoder) IsJSONHandle() bool {
+	return f.e.js
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
 func (f genHelperEncoder) HasExtensions() bool {
 	return len(f.e.h.extHandle) != 0
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
 func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
-	if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
+	rt := reflect.TypeOf(v)
+	if rt.Kind() == reflect.Ptr {
+		rt = rt.Elem()
+	}
+	rtid := reflect.ValueOf(rt).Pointer()
+	if xfFn := f.e.h.getExt(rtid); xfFn != nil {
 		f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
 		return true
 	}
 	return false
 }
 
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncSendContainerState(c containerState) {
+	if f.e.cr != nil {
+		f.e.cr.sendContainerState(c)
+	}
+}
+
 // ---------------- DECODER FOLLOWS -----------------
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@@ -202,27 +140,19 @@ func (f genHelperDecoder) DecBinary() bool {
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
+func (f genHelperDecoder) DecSwallow() {
+	f.d.swallow()
+}
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperDecoder) DecScratchBuffer() []byte {
 	return f.d.b[:]
 }
 
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
-	return &f.d.b
-}
-
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
 	// println(">>>>>>>>> DecFallback")
-	rv := reflect.ValueOf(iv)
-	if chkPtr {
-		rv = f.d.ensureDecodeable(rv)
-	}
-	f.d.decodeValue(rv, nil, false)
-	// f.d.decodeValueFallback(rv)
+	f.d.decodeI(iv, chkPtr, false, false, false)
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@@ -242,7 +172,7 @@ func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
-	fnerr := tm.UnmarshalText(f.d.d.DecodeStringAsBytes())
+	fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true))
 	if fnerr != nil {
 		panic(fnerr)
 	}
@@ -250,7 +180,7 @@ func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
-	// bs := f.dd.DecodeStringAsBytes()
+	// bs := f.dd.DecodeBytes(f.d.b[:], true, true)
 	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
 	fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
 	if fnerr != nil {
@@ -260,63 +190,40 @@ func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
-	fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, true))
+	fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true))
 	if fnerr != nil {
 		panic(fnerr)
 	}
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: builtin no longer supported - so we make this method a no-op,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
-
-// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
-// 	// Note: builtin is no longer supported - so make this a no-op
-// 	if _, ok := f.d.hh.(*BincHandle); ok {
-// 		return timeTypId
-// 	}
-// 	return 0
-// }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) IsJSONHandle() bool {
-	return f.d.js
+func (f genHelperDecoder) DecRaw() []byte {
+	return f.d.raw()
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
-	return i2rtid(v)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
-	return f.d.h.getExt(rtid)
+func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
+	if _, ok := f.d.hh.(*BincHandle); ok {
+		return timeTypId
+	}
+	return 0
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
-	f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
+func (f genHelperDecoder) IsJSONHandle() bool {
+	return f.d.js
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
 func (f genHelperDecoder) HasExtensions() bool {
 	return len(f.d.h.extHandle) != 0
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
 func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
-	if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
+	rt := reflect.TypeOf(v).Elem()
+	rtid := reflect.ValueOf(rt).Pointer()
+	if xfFn := f.d.h.getExt(rtid); xfFn != nil {
 		f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
 		return true
 	}
@@ -324,12 +231,13 @@ func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
+func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) {
 	return decInferLen(clen, maxlen, unit)
 }
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: no longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
+func (f genHelperDecoder) DecSendContainerState(c containerState) {
+	if f.d.cr != nil {
+		f.d.cr.sendContainerState(c)
+	}
+}
diff --git a/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
new file mode 100644
index 000000000..ad99f6671
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
@@ -0,0 +1,372 @@
+/* // +build ignore */
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// ************************************************************
+// DO NOT EDIT.
+// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
+// ************************************************************
+
+package codec
+
+import (
+	"encoding"
+	"reflect"
+)
+
+// This file is used to generate helper code for codecgen. 
+// The values here i.e. genHelper(En|De)coder are not to be used directly by 
+// library users. They WILL change continuously and without notice.
+// 
+// To help enforce this, we create an unexported type with exported members.
+// The only way to get the type is via the one exported type that we control (somewhat).
+// 
+// When static codecs are created for types, they will use this value
+// to perform encoding or decoding of primitives or known slice or map types.
+
+// GenHelperEncoder is exported so that it can be used externally by codecgen.
+// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
+func GenHelperEncoder(e *Encoder) (genHelperEncoder, encDriver) {
+	return genHelperEncoder{e:e}, e.e 
+}
+
+// GenHelperDecoder is exported so that it can be used externally by codecgen.
+// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
+func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) {
+	return genHelperDecoder{d:d}, d.d 
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+type genHelperEncoder struct {
+	e *Encoder
+	F fastpathT 
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+type genHelperDecoder struct {
+	d *Decoder
+	F fastpathT 
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
+	return f.e.h
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBinary() bool {
+	return f.e.be // f.e.hh.isBinaryEncoding()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncFallback(iv interface{}) {
+	// println(">>>>>>>>> EncFallback")
+	f.e.encodeI(iv, false, false)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
+	bs, fnerr := iv.MarshalText()
+	f.e.marshal(bs, fnerr, false, c_UTF8)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
+	bs, fnerr := iv.MarshalJSON()
+	f.e.marshal(bs, fnerr, true, c_UTF8)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
+	bs, fnerr := iv.MarshalBinary()
+	f.e.marshal(bs, fnerr, false, c_RAW)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncRaw(iv Raw) {
+	f.e.raw(iv)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
+	if _, ok := f.e.hh.(*BincHandle); ok {
+		return timeTypId 
+	}
+	return 0
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) IsJSONHandle() bool {
+	return f.e.js
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) HasExtensions() bool {
+	return len(f.e.h.extHandle) != 0
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
+	rt := reflect.TypeOf(v)
+	if rt.Kind() == reflect.Ptr {
+		rt = rt.Elem()
+	}
+	rtid := reflect.ValueOf(rt).Pointer()
+	if xfFn := f.e.h.getExt(rtid); xfFn != nil {
+		f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
+		return true
+	}
+	return false 
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncSendContainerState(c containerState) {
+	if f.e.cr != nil {
+		f.e.cr.sendContainerState(c)
+	}
+}
+
+// ---------------- DECODER FOLLOWS -----------------
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBasicHandle() *BasicHandle {
+	return f.d.h
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBinary() bool {
+     return f.d.be // f.d.hh.isBinaryEncoding()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecSwallow() {
+	f.d.swallow()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecScratchBuffer() []byte {
+	return f.d.b[:]
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
+	// println(">>>>>>>>> DecFallback")
+	f.d.decodeI(iv, chkPtr, false, false, false)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
+	return f.d.decSliceHelperStart()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) {
+	f.d.structFieldNotFound(index, name)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
+	f.d.arrayCannotExpand(sliceLen, streamLen)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
+	fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true))
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
+	// bs := f.dd.DecodeBytes(f.d.b[:], true, true)
+	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
+	fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
+	fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true))
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecRaw() []byte {
+	return f.d.raw()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
+	if _, ok := f.d.hh.(*BincHandle); ok {
+		return timeTypId 
+	}
+	return 0
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) IsJSONHandle() bool {
+	return f.d.js 
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) HasExtensions() bool {
+	return len(f.d.h.extHandle) != 0
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
+	rt := reflect.TypeOf(v).Elem()
+	rtid := reflect.ValueOf(rt).Pointer()
+	if xfFn := f.d.h.getExt(rtid); xfFn != nil {
+		f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
+		return true
+	}
+	return false 
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) {
+	return decInferLen(clen, maxlen, unit)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecSendContainerState(c containerState) {
+	if f.d.cr != nil {
+		f.d.cr.sendContainerState(c)
+	}
+}
+
+{{/*
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncDriver() encDriver {
+	return f.e.e
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecDriver() decDriver {
+     return f.d.d
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncNil() {
+	f.e.e.EncodeNil()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBytes(v []byte) {
+	f.e.e.EncodeStringBytes(c_RAW, v)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncArrayStart(length int) {
+	f.e.e.EncodeArrayStart(length)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncArrayEnd() {
+	f.e.e.EncodeArrayEnd()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncArrayEntrySeparator() {
+	f.e.e.EncodeArrayEntrySeparator()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncMapStart(length int) {
+	f.e.e.EncodeMapStart(length)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncMapEnd() {
+	f.e.e.EncodeMapEnd()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncMapEntrySeparator() {
+	f.e.e.EncodeMapEntrySeparator()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncMapKVSeparator() {
+	f.e.e.EncodeMapKVSeparator()
+}
+
+// ---------
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBytes(v *[]byte) {
+	*v = f.d.d.DecodeBytes(*v)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecTryNil() bool {
+	return f.d.d.TryDecodeAsNil()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecContainerIsNil() (b bool) {
+	return f.d.d.IsContainerType(valueTypeNil)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecContainerIsMap() (b bool) {
+	return f.d.d.IsContainerType(valueTypeMap)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecContainerIsArray() (b bool) {
+	return f.d.d.IsContainerType(valueTypeArray)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecCheckBreak() bool {
+	return f.d.d.CheckBreak()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecMapStart() int {
+	return f.d.d.ReadMapStart()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecArrayStart() int {
+	return f.d.d.ReadArrayStart()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecMapEnd() {
+	f.d.d.ReadMapEnd()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecArrayEnd() {
+	f.d.d.ReadArrayEnd()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecArrayEntrySeparator() {
+	f.d.d.ReadArrayEntrySeparator()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecMapEntrySeparator() {
+	f.d.d.ReadMapEntrySeparator()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecMapKVSeparator() {
+	f.d.d.ReadMapKVSeparator()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) ReadStringAsBytes(bs []byte) []byte {
+	return f.d.d.DecodeStringAsBytes(bs)
+}
+
+
+// -- encode calls (primitives)
+{{range .Values}}{{if .Primitive }}{{if ne .Primitive "interface{}" }}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) {{ .MethodNamePfx "Enc" true }}(v {{ .Primitive }}) {
+	ee := f.e.e
+	{{ encmd .Primitive "v" }}
+}
+{{ end }}{{ end }}{{ end }}
+
+// -- decode calls (primitives)
+{{range .Values}}{{if .Primitive }}{{if ne .Primitive "interface{}" }}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) {{ .MethodNamePfx "Dec" true }}(vp *{{ .Primitive }}) {
+	dd := f.d.d
+	*vp = {{ decmd .Primitive }}
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) {{ .MethodNamePfx "Read" true }}() (v {{ .Primitive }}) {
+	dd := f.d.d
+	v = {{ decmd .Primitive }}
+	return
+}
+{{ end }}{{ end }}{{ end }}
+
+
+// -- encode calls (slices/maps)
+{{range .Values}}{{if not .Primitive }}{{if .Slice }}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) {{ .MethodNamePfx "Enc" false }}(v []{{ .Elem }}) { {{ else }}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) {{ .MethodNamePfx "Enc" false }}(v map[{{ .MapKey }}]{{ .Elem }}) { {{end}}
+	f.F.{{ .MethodNamePfx "Enc" false }}V(v, false, f.e)
+}
+{{ end }}{{ end }}
+
+// -- decode calls (slices/maps) 
+{{range .Values}}{{if not .Primitive }}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+{{if .Slice }}func (f genHelperDecoder) {{ .MethodNamePfx "Dec" false }}(vp *[]{{ .Elem }}) { 
+{{else}}func (f genHelperDecoder) {{ .MethodNamePfx "Dec" false }}(vp *map[{{ .MapKey }}]{{ .Elem }}) { {{end}}
+	v, changed := f.F.{{ .MethodNamePfx "Dec" false }}V(*vp, false, true, f.d)
+	if changed {
+		*vp = v 
+	}
+}
+{{ end }}{{ end }}
+*/}}
diff --git a/vendor/github.com/ugorji/go/codec/gen.generated.go b/vendor/github.com/ugorji/go/codec/gen.generated.go
index 240ba9f8c..2ace97b78 100644
--- a/vendor/github.com/ugorji/go/codec/gen.generated.go
+++ b/vendor/github.com/ugorji/go/codec/gen.generated.go
@@ -1,5 +1,3 @@
-// +build codecgen.exec
-
 // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
@@ -12,22 +10,21 @@ const genDecMapTmpl = `
 {{var "l"}} := r.ReadMapStart()
 {{var "bh"}} := z.DecBasicHandle()
 if {{var "v"}} == nil {
-	{{var "rl"}} := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
+	{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
 	{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
 	*{{ .Varname }} = {{var "v"}}
 }
 var {{var "mk"}} {{ .KTyp }}
 var {{var "mv"}} {{ .Typ }}
-var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
+var {{var "mg"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
 if {{var "bh"}}.MapValueReset {
 	{{if decElemKindPtr}}{{var "mg"}} = true
 	{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
 	{{else if not decElemKindImmutable}}{{var "mg"}} = true
 	{{end}} }
-if {{var "l"}} != 0 {
-{{var "hl"}} := {{var "l"}} > 0 
-	for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
-	r.ReadMapElemKey() {{/* z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) */}}
+if {{var "l"}} > 0  {
+for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ {
+	z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }})
 	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
 {{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
 		{{var "mk"}} = string({{var "bv"}})
@@ -39,17 +36,34 @@ if {{var "l"}} != 0 {
 			{{var "ms"}} = false
 		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
 	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
-	r.ReadMapElemValue() {{/* z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) */}}
-	{{var "mdn"}} = false
-	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y }}
-	if {{var "mdn"}} {
-		if {{ var "bh" }}.DeleteOnNilMapValue { delete({{var "v"}}, {{var "mk"}}) } else { {{var "v"}}[{{var "mk"}}] = {{decElemZero}} }
-	} else if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
+	z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }})
+	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
+	if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
+		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
+	}
+}
+} else if {{var "l"}} < 0  {
+for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ {
+	z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }})
+	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
+{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
+		{{var "mk"}} = string({{var "bv"}})
+	}{{ end }}{{if decElemKindPtr}}
+	{{var "ms"}} = true {{ end }}
+	if {{var "mg"}} {
+		{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] 
+		if {{var "mok"}} {
+			{{var "ms"}} = false
+		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
+	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
+	z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }})
+	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
+	if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
 		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
 	}
 }
 } // else len==0: TODO: Should we clear map entries?
-r.ReadMapEnd() {{/* z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) */}}
+z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }})
 `
 
 const genDecListTmpl = `
@@ -64,68 +78,94 @@ if {{var "l"}} == 0 {
 	} else if len({{var "v"}}) != 0 {
 		{{var "v"}} = {{var "v"}}[:0]
 		{{var "c"}} = true
-	} {{else if isChan }}if {{var "v"}} == nil {
+	} {{end}} {{if isChan }}if {{var "v"}} == nil {
 		{{var "v"}} = make({{ .CTyp }}, 0)
 		{{var "c"}} = true
 	} {{end}}
-} else {
-	{{var "hl"}} := {{var "l"}} > 0
-	var {{var "rl"}} int
-	_ =  {{var "rl"}}
-	{{if isSlice }} if {{var "hl"}} {
+} else if {{var "l"}} > 0 {
+	{{if isChan }}if {{var "v"}} == nil {
+		{{var "rl"}}, _ = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+		{{var "v"}} = make({{ .CTyp }}, {{var "rl"}})
+		{{var "c"}} = true
+	}
+	for {{var "r"}} := 0; {{var "r"}} < {{var "l"}}; {{var "r"}}++ {
+		{{var "h"}}.ElemContainerState({{var "r"}})
+		var {{var "t"}} {{ .Typ }}
+		{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }}
+		{{var "v"}} <- {{var "t"}}
+	}
+	{{ else }}	var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
+	var {{var "rt"}} bool {{/* truncated */}}
+	_, _ = {{var "rl"}}, {{var "rt"}}
+	{{var "rr"}} = {{var "l"}} // len({{var "v"}})
 	if {{var "l"}} > cap({{var "v"}}) {
-		{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
-		if {{var "rl"}} <= cap({{var "v"}}) {
-			{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
+		{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
+		{{ else }}{{if not .Immutable }}
+		{{var "rg"}} := len({{var "v"}}) > 0
+		{{var "v2"}} := {{var "v"}} {{end}}
+		{{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+		if {{var "rt"}} {
+			if {{var "rl"}} <= cap({{var "v"}}) {
+				{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
+			} else {
+				{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
+			}
 		} else {
 			{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
 		}
 		{{var "c"}} = true
-	} else if {{var "l"}} != len({{var "v"}}) {
+		{{var "rr"}} = len({{var "v"}}) {{if not .Immutable }}
+			if {{var "rg"}} { copy({{var "v"}}, {{var "v2"}}) } {{end}} {{end}}{{/* end not Immutable, isArray */}}
+	} {{if isSlice }} else if {{var "l"}} != len({{var "v"}}) {
 		{{var "v"}} = {{var "v"}}[:{{var "l"}}]
 		{{var "c"}} = true
+	} {{end}}	{{/* end isSlice:47 */}} 
+	{{var "j"}} := 0
+	for ; {{var "j"}} < {{var "rr"}} ; {{var "j"}}++ {
+		{{var "h"}}.ElemContainerState({{var "j"}})
+		{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
 	}
-	} {{end}}
-	var {{var "j"}} int 
-    // var {{var "dn"}} bool 
-	for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
-		{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
-			if {{var "hl"}} {
-				{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
-			} else {
-				{{var "rl"}} = {{if isSlice}}8{{else if isChan}}64{{end}}
-			}
-			{{var "v"}} = make({{if isSlice}}[]{{ .Typ }}{{else if isChan}}{{.CTyp}}{{end}}, {{var "rl"}})
-			{{var "c"}} = true 
-		}{{end}}
+	{{if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ {
+		{{var "h"}}.ElemContainerState({{var "j"}})
+		z.DecSwallow()
+	}
+	{{ else }}if {{var "rt"}} {
+		for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ {
+			{{var "v"}} = append({{var "v"}}, {{ zero}})
+			{{var "h"}}.ElemContainerState({{var "j"}})
+			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
+		}
+	} {{end}} {{/* end isArray:56 */}}
+	{{end}} {{/* end isChan:16 */}}
+} else { {{/* len < 0 */}}
+	{{var "j"}} := 0
+	for ; !r.CheckBreak(); {{var "j"}}++ {
+		{{if isChan }}
 		{{var "h"}}.ElemContainerState({{var "j"}})
-        {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */}}
-        {{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
-		{{ decLineVar $x }}
-		{{var "v"}} <- {{ $x }}
-        // println(">>>> sending ", {{ $x }}, " into ", {{var "v"}}) // TODO: remove this
-        {{else}}{{/* // if indefinite, etc, then expand the slice if necessary */}}
-		var {{var "db"}} bool
+		var {{var "t"}} {{ .Typ }}
+		{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }}
+		{{var "v"}} <- {{var "t"}} 
+		{{ else }}
 		if {{var "j"}} >= len({{var "v"}}) {
-			{{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
-			{{var "c"}} = true
-			{{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
-			{{end}}
+			{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1)
+			{{ else }}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }}
+			{{var "c"}} = true {{end}}
 		}
-		if {{var "db"}} {
-			z.DecSwallow()
-		} else {
+		{{var "h"}}.ElemContainerState({{var "j"}})
+		if {{var "j"}} < len({{var "v"}}) {
 			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
+		} else {
+			z.DecSwallow()
 		}
-        {{end}}
+		{{end}}
 	}
-	{{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
+	{{if isSlice }}if {{var "j"}} < len({{var "v"}}) {
 		{{var "v"}} = {{var "v"}}[:{{var "j"}}]
 		{{var "c"}} = true
 	} else if {{var "j"}} == 0 && {{var "v"}} == nil {
-		{{var "v"}} = make([]{{ .Typ }}, 0)
+		{{var "v"}} = []{{ .Typ }}{}
 		{{var "c"}} = true
-	} {{end}}
+	}{{end}}
 }
 {{var "h"}}.End()
 {{if not isArray }}if {{var "c"}} { 
@@ -133,32 +173,3 @@ if {{var "l"}} == 0 {
 }{{end}}
 `
 
-const genEncChanTmpl = `
-{{.Label}}:
-switch timeout{{.Sfx}} :=  z.EncBasicHandle().ChanRecvTimeout; {
-case timeout{{.Sfx}} == 0: // only consume available
-	for {
-		select {
-		case b{{.Sfx}} := <-{{.Chan}}:
-			{{ .Slice }} = append({{.Slice}}, b{{.Sfx}})
-		default:
-			break {{.Label}}
-		}
-	}
-case timeout{{.Sfx}} > 0: // consume until timeout
-	tt{{.Sfx}} := time.NewTimer(timeout{{.Sfx}})
-	for {
-		select {
-		case b{{.Sfx}} := <-{{.Chan}}:
-			{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
-		case <-tt{{.Sfx}}.C:
-			// close(tt.C)
-			break {{.Label}}
-		}
-	}
-default: // consume until close
-	for b{{.Sfx}} := range {{.Chan}} {
-		{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
-	}
-}
-`
diff --git a/vendor/github.com/ugorji/go/codec/gen.go b/vendor/github.com/ugorji/go/codec/gen.go
index b4c4031ff..c4944dbff 100644
--- a/vendor/github.com/ugorji/go/codec/gen.go
+++ b/vendor/github.com/ugorji/go/codec/gen.go
@@ -1,6 +1,4 @@
-// +build codecgen.exec
-
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
@@ -30,6 +28,7 @@ import (
 // codecgen supports the full cycle of reflection-based codec:
 //    - RawExt
 //    - Raw
+//    - Builtins
 //    - Extensions
 //    - (Binary|Text|JSON)(Unm|M)arshal
 //    - generic by-kind
@@ -81,10 +80,6 @@ import (
 // Note:
 //   It was a conscious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil.
 //   This way, there isn't a function call overhead just to see that we should not enter a block of code.
-//
-// Note:
-//   codecgen-generated code depends on the variables defined by fast-path.generated.go.
-//   consequently, you cannot run with tags "codecgen notfastpath".
 
 // GenVersion is the current version of codecgen.
 //
@@ -99,10 +94,7 @@ import (
 //     changes in signature of some unpublished helper methods and codecgen cmdline arguments.
 // v4: Removed separator support from (en|de)cDriver, and refactored codec(gen)
 // v5: changes to support faster json decoding. Let encoder/decoder maintain state of collections.
-// v6: removed unsafe from gen, and now uses codecgen.exec tag
-// v7:
-// v8: current - we now maintain compatibility with old generated code.
-const genVersion = 8
+const GenVersion = 5
 
 const (
 	genCodecPkg        = "codec1978"
@@ -130,27 +122,13 @@ const (
 )
 
 var (
-	errGenAllTypesSamePkg  = errors.New("All types must be in the same package")
-	errGenExpectArrayOrMap = errors.New("unexpected type. Expecting array/map/slice")
-
-	genBase64enc  = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__")
-	genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
+	genAllTypesSamePkgErr  = errors.New("All types must be in the same package")
+	genExpectArrayOrMapErr = errors.New("unexpected type. Expecting array/map/slice")
+	genBase64enc           = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__")
+	genQNameRegex          = regexp.MustCompile(`[A-Za-z_.]+`)
+	genCheckVendor         bool
 )
 
-type genBuf struct {
-	buf []byte
-}
-
-func (x *genBuf) s(s string) *genBuf              { x.buf = append(x.buf, s...); return x }
-func (x *genBuf) b(s []byte) *genBuf              { x.buf = append(x.buf, s...); return x }
-func (x *genBuf) v() string                       { return string(x.buf) }
-func (x *genBuf) f(s string, args ...interface{}) { x.s(fmt.Sprintf(s, args...)) }
-func (x *genBuf) reset() {
-	if x.buf != nil {
-		x.buf = x.buf[:0]
-	}
-}
-
 // genRunner holds some state used during a Gen run.
 type genRunner struct {
 	w io.Writer      // output
@@ -169,7 +147,8 @@ type genRunner struct {
 	is map[reflect.Type]struct{} // types seen during import search
 	bp string                    // base PkgPath, for which we are generating for
 
-	cpfx string // codec package prefix
+	cpfx   string // codec package prefix
+	unsafe bool   // is unsafe to be used in generated code?
 
 	tm map[reflect.Type]struct{} // types for which enc/dec must be generated
 	ts []reflect.Type            // types for which enc/dec must be generated
@@ -179,16 +158,13 @@ type genRunner struct {
 
 	ti *TypeInfos
 	// rr *rand.Rand // random generator for file-specific types
-
-	nx bool // no extensions
 }
 
 // Gen will write a complete go file containing Selfer implementations for each
 // type passed. All the types must be in the same package.
 //
-// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINUOUSLY WITHOUT NOTICE.
-func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
-	ti *TypeInfos, typ ...reflect.Type) {
+// Library users: *DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.*
+func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeInfos, typ ...reflect.Type) {
 	// All types passed to this method do not have a codec.Selfer method implemented directly.
 	// codecgen already checks the AST and skips any types that define the codec.Selfer methods.
 	// Consequently, there's no need to check and trim them if they implement codec.Selfer
@@ -197,19 +173,19 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 		return
 	}
 	x := genRunner{
-		w:   w,
-		t:   typ,
-		te:  make(map[uintptr]bool),
-		td:  make(map[uintptr]bool),
-		im:  make(map[string]reflect.Type),
-		imn: make(map[string]string),
-		is:  make(map[reflect.Type]struct{}),
-		tm:  make(map[reflect.Type]struct{}),
-		ts:  []reflect.Type{},
-		bp:  genImportPath(typ[0]),
-		xs:  uid,
-		ti:  ti,
-		nx:  noExtensions,
+		unsafe: useUnsafe,
+		w:      w,
+		t:      typ,
+		te:     make(map[uintptr]bool),
+		td:     make(map[uintptr]bool),
+		im:     make(map[string]reflect.Type),
+		imn:    make(map[string]string),
+		is:     make(map[reflect.Type]struct{}),
+		tm:     make(map[reflect.Type]struct{}),
+		ts:     []reflect.Type{},
+		bp:     genImportPath(typ[0]),
+		xs:     uid,
+		ti:     ti,
 	}
 	if x.ti == nil {
 		x.ti = defTypeInfos
@@ -225,7 +201,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 	for _, t := range typ {
 		// fmt.Printf("###########: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name())
 		if genImportPath(t) != x.bp {
-			panic(errGenAllTypesSamePkg)
+			panic(genAllTypesSamePkgErr)
 		}
 		x.genRefPkgs(t)
 	}
@@ -235,7 +211,10 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 	}
 	x.line(`
 
-// Code generated by codecgen - DO NOT EDIT.
+// ************************************************************
+// DO NOT EDIT.
+// THIS FILE IS AUTO-GENERATED BY codecgen.
+// ************************************************************
 
 `)
 	x.line("package " + pkgName)
@@ -247,20 +226,19 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 	}
 	// use a sorted set of im keys, so that we can get consistent output
 	imKeys := make([]string, 0, len(x.im))
-	for k := range x.im {
+	for k, _ := range x.im {
 		imKeys = append(imKeys, k)
 	}
 	sort.Strings(imKeys)
 	for _, k := range imKeys { // for k, _ := range x.im {
-		if k == x.imn[k] {
-			x.linef("\"%s\"", k)
-		} else {
-			x.linef("%s \"%s\"", x.imn[k], k)
-		}
+		x.linef("%s \"%s\"", x.imn[k], k)
 	}
 	// add required packages
-	for _, k := range [...]string{"runtime", "errors", "strconv"} { // "reflect", "fmt"
+	for _, k := range [...]string{"reflect", "unsafe", "runtime", "fmt", "errors"} {
 		if _, ok := x.im[k]; !ok {
+			if k == "unsafe" && !x.unsafe {
+				continue
+			}
 			x.line("\"" + k + "\"")
 		}
 	}
@@ -269,36 +247,41 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 
 	x.line("const (")
 	x.linef("// ----- content types ----")
-	x.linef("codecSelferCcUTF8%s = %v", x.xs, int64(cUTF8))
-	x.linef("codecSelferCcRAW%s = %v", x.xs, int64(cRAW))
+	x.linef("codecSelferC_UTF8%s = %v", x.xs, int64(c_UTF8))
+	x.linef("codecSelferC_RAW%s = %v", x.xs, int64(c_RAW))
 	x.linef("// ----- value types used ----")
-	for _, vt := range [...]valueType{
-		valueTypeArray, valueTypeMap, valueTypeString,
-		valueTypeInt, valueTypeUint, valueTypeFloat} {
-		x.linef("codecSelferValueType%s%s = %v", vt.String(), x.xs, int64(vt))
-	}
-
-	x.linef("codecSelferBitsize%s = uint8(32 << (^uint(0) >> 63))", x.xs)
+	x.linef("codecSelferValueTypeArray%s = %v", x.xs, int64(valueTypeArray))
+	x.linef("codecSelferValueTypeMap%s = %v", x.xs, int64(valueTypeMap))
+	x.linef("// ----- containerStateValues ----")
+	x.linef("codecSelfer_containerMapKey%s = %v", x.xs, int64(containerMapKey))
+	x.linef("codecSelfer_containerMapValue%s = %v", x.xs, int64(containerMapValue))
+	x.linef("codecSelfer_containerMapEnd%s = %v", x.xs, int64(containerMapEnd))
+	x.linef("codecSelfer_containerArrayElem%s = %v", x.xs, int64(containerArrayElem))
+	x.linef("codecSelfer_containerArrayEnd%s = %v", x.xs, int64(containerArrayEnd))
 	x.line(")")
 	x.line("var (")
-	x.line("errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + " = errors.New(`only encoded map or array can be decoded into a struct`)")
+	x.line("codecSelferBitsize" + x.xs + " = uint8(reflect.TypeOf(uint(0)).Bits())")
+	x.line("codecSelferOnlyMapOrArrayEncodeToStructErr" + x.xs + " = errors.New(`only encoded map or array can be decoded into a struct`)")
 	x.line(")")
 	x.line("")
 
+	if x.unsafe {
+		x.line("type codecSelferUnsafeString" + x.xs + " struct { Data uintptr; Len int}")
+		x.line("")
+	}
 	x.hn = "codecSelfer" + x.xs
 	x.line("type " + x.hn + " struct{}")
 	x.line("")
 
 	x.varsfxreset()
 	x.line("func init() {")
-	x.linef("if %sGenVersion != %v {", x.cpfx, genVersion)
+	x.linef("if %sGenVersion != %v {", x.cpfx, GenVersion)
 	x.line("_, file, _, _ := runtime.Caller(0)")
-	x.outf(`panic("codecgen version mismatch: current: %v, need " + strconv.FormatInt(int64(%sGenVersion), 10) + ". Re-generate file: " + file)`, genVersion, x.cpfx)
-	// x.out(`panic(fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", `)
-	// x.linef(`%v, %sGenVersion, file))`, genVersion, x.cpfx)
+	x.line(`err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", `)
+	x.linef(`%v, %sGenVersion, file)`, GenVersion, x.cpfx)
+	x.line("panic(err)")
 	x.linef("}")
 	x.line("if false { // reference the types, but skip this branch at build/run time")
-	// x.line("_ = strconv.ParseInt")
 	var n int
 	// for k, t := range x.im {
 	for _, k := range imKeys {
@@ -306,6 +289,10 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 		x.linef("var v%v %s.%s", n, x.imn[k], t.Name())
 		n++
 	}
+	if x.unsafe {
+		x.linef("var v%v unsafe.Pointer", n)
+		n++
+	}
 	if n > 0 {
 		x.out("_")
 		for i := 1; i < n; i++ {
@@ -328,7 +315,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 	}
 
 	for _, t := range x.ts {
-		rtid := rt2id(t)
+		rtid := reflect.ValueOf(t).Pointer()
 		// generate enc functions for all these slice/map types.
 		x.varsfxreset()
 		x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx)
@@ -339,7 +326,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 		case reflect.Map:
 			x.encMapFallback("v", t)
 		default:
-			panic(errGenExpectArrayOrMap)
+			panic(genExpectArrayOrMapErr)
 		}
 		x.line("}")
 		x.line("")
@@ -354,7 +341,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 		case reflect.Map:
 			x.decMapFallback("v", rtid, t)
 		default:
-			panic(errGenExpectArrayOrMap)
+			panic(genExpectArrayOrMapErr)
 		}
 		x.line("}")
 		x.line("")
@@ -390,6 +377,7 @@ func (x *genRunner) genRefPkgs(t reflect.Type) {
 	if _, ok := x.is[t]; ok {
 		return
 	}
+	// fmt.Printf(">>>>>>: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name())
 	x.is[t] = struct{}{}
 	tpkg, tname := genImportPath(t), t.Name()
 	if tpkg != "" && tpkg != x.bp && tpkg != x.cp && tname != "" && tname[0] >= 'A' && tname[0] <= 'Z' {
@@ -418,6 +406,13 @@ func (x *genRunner) genRefPkgs(t reflect.Type) {
 	}
 }
 
+func (x *genRunner) line(s string) {
+	x.out(s)
+	if len(s) == 0 || s[len(s)-1] != '\n' {
+		x.out("\n")
+	}
+}
+
 func (x *genRunner) varsfx() string {
 	x.c++
 	return strconv.FormatUint(x.c, 10)
@@ -428,31 +423,17 @@ func (x *genRunner) varsfxreset() {
 }
 
 func (x *genRunner) out(s string) {
-	_, err := io.WriteString(x.w, s)
-	if err != nil {
-		panic(err)
-	}
-}
-
-func (x *genRunner) outf(s string, params ...interface{}) {
-	_, err := fmt.Fprintf(x.w, s, params...)
-	if err != nil {
+	if _, err := io.WriteString(x.w, s); err != nil {
 		panic(err)
 	}
 }
 
-func (x *genRunner) line(s string) {
-	x.out(s)
-	if len(s) == 0 || s[len(s)-1] != '\n' {
-		x.out("\n")
-	}
+func (x *genRunner) linef(s string, params ...interface{}) {
+	x.line(fmt.Sprintf(s, params...))
 }
 
-func (x *genRunner) linef(s string, params ...interface{}) {
-	x.outf(s, params...)
-	if len(s) == 0 || s[len(s)-1] != '\n' {
-		x.out("\n")
-	}
+func (x *genRunner) outf(s string, params ...interface{}) {
+	x.out(fmt.Sprintf(s, params...))
 }
 
 func (x *genRunner) genTypeName(t reflect.Type) (n string) {
@@ -525,23 +506,23 @@ func (x *genRunner) selfer(encode bool) {
 	t := x.tc
 	t0 := t
 	// always make decode use a pointer receiver,
-	// and structs/arrays always use a ptr receiver (encode|decode)
-	isptr := !encode || t.Kind() == reflect.Array || (t.Kind() == reflect.Struct && t != timeTyp)
+	// and structs always use a ptr receiver (encode|decode)
+	isptr := !encode || t.Kind() == reflect.Struct
 	x.varsfxreset()
-
-	fnSigPfx := "func (" + genTopLevelVarName + " "
+	fnSigPfx := "func (x "
 	if isptr {
 		fnSigPfx += "*"
 	}
 	fnSigPfx += x.genTypeName(t)
-	x.out(fnSigPfx)
 
+	x.out(fnSigPfx)
 	if isptr {
 		t = reflect.PtrTo(t)
 	}
 	if encode {
 		x.line(") CodecEncodeSelf(e *" + x.cpfx + "Encoder) {")
 		x.genRequiredMethodVars(true)
+		// x.enc(genTopLevelVarName, t)
 		x.encVar(genTopLevelVarName, t)
 	} else {
 		x.line(") CodecDecodeSelf(d *" + x.cpfx + "Decoder) {")
@@ -550,7 +531,7 @@ func (x *genRunner) selfer(encode bool) {
 		// or way to elegantly handle that, and also setting it to a
 		// non-nil value doesn't affect the pointer passed.
 		// x.decVar(genTopLevelVarName, t, false)
-		x.dec(genTopLevelVarName, t0, true)
+		x.dec(genTopLevelVarName, t0)
 	}
 	x.line("}")
 	x.line("")
@@ -564,21 +545,21 @@ func (x *genRunner) selfer(encode bool) {
 		x.out(fnSigPfx)
 		x.line(") codecDecodeSelfFromMap(l int, d *" + x.cpfx + "Decoder) {")
 		x.genRequiredMethodVars(false)
-		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleConsolidated)
+		x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, genStructMapStyleConsolidated)
 		x.line("}")
 		x.line("")
 	} else {
 		x.out(fnSigPfx)
 		x.line(") codecDecodeSelfFromMapLenPrefix(l int, d *" + x.cpfx + "Decoder) {")
 		x.genRequiredMethodVars(false)
-		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleLenPrefix)
+		x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, genStructMapStyleLenPrefix)
 		x.line("}")
 		x.line("")
 
 		x.out(fnSigPfx)
 		x.line(") codecDecodeSelfFromMapCheckBreak(l int, d *" + x.cpfx + "Decoder) {")
 		x.genRequiredMethodVars(false)
-		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleCheckBreak)
+		x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, genStructMapStyleCheckBreak)
 		x.line("}")
 		x.line("")
 	}
@@ -587,24 +568,18 @@ func (x *genRunner) selfer(encode bool) {
 	x.out(fnSigPfx)
 	x.line(") codecDecodeSelfFromArray(l int, d *" + x.cpfx + "Decoder) {")
 	x.genRequiredMethodVars(false)
-	x.decStructArray(genTopLevelVarName, "l", "return", rt2id(t0), t0)
+	x.decStructArray(genTopLevelVarName, "l", "return", reflect.ValueOf(t0).Pointer(), t0)
 	x.line("}")
 	x.line("")
 
 }
 
 // used for chan, array, slice, map
-func (x *genRunner) xtraSM(varname string, t reflect.Type, encode, isptr bool) {
-	var ptrPfx, addrPfx string
-	if isptr {
-		ptrPfx = "*"
-	} else {
-		addrPfx = "&"
-	}
+func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) {
 	if encode {
-		x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), ptrPfx, x.genTypeName(t), varname)
+		x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), varname)
 	} else {
-		x.linef("h.dec%s((*%s)(%s%s), d)", x.genMethodNameT(t), x.genTypeName(t), addrPfx, varname)
+		x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname)
 	}
 	x.registerXtraT(t)
 }
@@ -643,23 +618,17 @@ func (x *genRunner) encVar(varname string, t reflect.Type) {
 	if checkNil {
 		x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
 	}
-
 	switch t.Kind() {
 	case reflect.Ptr:
-		telem := t.Elem()
-		tek := telem.Kind()
-		if tek == reflect.Array || (tek == reflect.Struct && telem != timeTyp) {
+		switch t.Elem().Kind() {
+		case reflect.Struct, reflect.Array:
 			x.enc(varname, genNonPtr(t))
-			break
+		default:
+			i := x.varsfx()
+			x.line(genTempVarPfx + i + " := *" + varname)
+			x.enc(genTempVarPfx+i, genNonPtr(t))
 		}
-		i := x.varsfx()
-		x.line(genTempVarPfx + i + " := *" + varname)
-		x.enc(genTempVarPfx+i, genNonPtr(t))
 	case reflect.Struct, reflect.Array:
-		if t == timeTyp {
-			x.enc(varname, t)
-			break
-		}
 		i := x.varsfx()
 		x.line(genTempVarPfx + i + " := &" + varname)
 		x.enc(genTempVarPfx+i, t)
@@ -673,33 +642,29 @@ func (x *genRunner) encVar(varname string, t reflect.Type) {
 
 }
 
-// enc will encode a variable (varname) of type t, where t represents T.
-// if t is !time.Time and t is of kind reflect.Struct or reflect.Array, varname is of type *T
-// (to prevent copying),
-// else t is of type T
+// enc will encode a variable (varname) of type t,
+// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type ptrTo(T) (to prevent copying)
 func (x *genRunner) enc(varname string, t reflect.Type) {
-	rtid := rt2id(t)
-	ti2 := x.ti.get(rtid, t)
+	rtid := reflect.ValueOf(t).Pointer()
 	// We call CodecEncodeSelf if one of the following are honored:
 	//   - the type already implements Selfer, call that
 	//   - the type has a Selfer implementation just created, use that
 	//   - the type is in the list of the ones we will generate for, but it is not currently being generated
 
 	mi := x.varsfx()
-	// tptr := reflect.PtrTo(t)
+	tptr := reflect.PtrTo(t)
 	tk := t.Kind()
 	if x.checkForSelfer(t, varname) {
-		if tk == reflect.Array || (tk == reflect.Struct && rtid != timeTypId) { // varname is of type *T
-			// if tptr.Implements(selferTyp) || t.Implements(selferTyp) {
-			if ti2.isFlag(typeInfoFlagIsZeroerPtr) || ti2.isFlag(typeInfoFlagIsZeroer) {
+		if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T
+			if tptr.Implements(selferTyp) || t.Implements(selferTyp) {
 				x.line(varname + ".CodecEncodeSelf(e)")
 				return
 			}
 		} else { // varname is of type T
-			if ti2.cs { // t.Implements(selferTyp) {
+			if t.Implements(selferTyp) {
 				x.line(varname + ".CodecEncodeSelf(e)")
 				return
-			} else if ti2.csp { // tptr.Implements(selferTyp) {
+			} else if tptr.Implements(selferTyp) {
 				x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname)
 				x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi)
 				return
@@ -731,53 +696,57 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 	}
 
 	// check if
-	//   - type is time.Time, RawExt, Raw
+	//   - type is RawExt, Raw
 	//   - the type implements (Text|JSON|Binary)(Unm|M)arshal
-
+	x.linef("%sm%s := z.EncBinary()", genTempVarPfx, mi)
+	x.linef("_ = %sm%s", genTempVarPfx, mi)
 	x.line("if false {")           //start if block
 	defer func() { x.line("}") }() //end if block
 
-	if t == timeTyp {
-		x.linef("} else { r.EncodeTime(%s)", varname)
-		return
-	}
 	if t == rawTyp {
-		x.linef("} else { z.EncRaw(%s)", varname)
+		x.linef("} else { z.EncRaw(%v)", varname)
 		return
 	}
 	if t == rawExtTyp {
-		x.linef("} else { r.EncodeRawExt(%s, e)", varname)
+		x.linef("} else { r.EncodeRawExt(%v, e)", varname)
 		return
 	}
+	// HACK: Support for Builtins.
+	//       Currently, only Binc supports builtins, and the only builtin type is time.Time.
+	//       Have a method that returns the rtid for time.Time if Handle is Binc.
+	if t == timeTyp {
+		vrtid := genTempVarPfx + "m" + x.varsfx()
+		x.linef("} else if %s := z.TimeRtidIfBinc(); %s != 0 { ", vrtid, vrtid)
+		x.linef("r.EncodeBuiltin(%s, %s)", vrtid, varname)
+	}
 	// only check for extensions if the type is named, and has a packagePath.
-	var arrayOrStruct = tk == reflect.Array || tk == reflect.Struct // meaning varname if of type *T
-	if !x.nx && genImportPath(t) != "" && t.Name() != "" {
-		yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
-		x.linef("} else if %s := z.Extension(z.I2Rtid(%s)); %s != nil { z.EncExtension(%s, %s) ", yy, varname, yy, varname, yy)
-	}
-	if arrayOrStruct { // varname is of type *T
-		if ti2.bm || ti2.bmp { // t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
-			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(%v) ", varname)
+	if genImportPath(t) != "" && t.Name() != "" {
+		// first check if extensions are configued, before doing the interface conversion
+		x.linef("} else if z.HasExtensions() && z.EncExt(%s) {", varname)
+	}
+	if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T
+		if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
+			x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
 		}
-		if ti2.jm || ti2.jmp { // t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", varname)
-		} else if ti2.tm || ti2.tmp { // t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(%v) ", varname)
+		if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
+			x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
+		} else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
+			x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
 		}
 	} else { // varname is of type T
-		if ti2.bm { // t.Implements(binaryMarshalerTyp) {
-			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(%v) ", varname)
-		} else if ti2.bmp { // tptr.Implements(binaryMarshalerTyp) {
-			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(&%v) ", varname)
+		if t.Implements(binaryMarshalerTyp) {
+			x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
+		} else if tptr.Implements(binaryMarshalerTyp) {
+			x.linef("} else if %sm%s { z.EncBinaryMarshal(&%v) ", genTempVarPfx, mi, varname)
 		}
-		if ti2.jm { // t.Implements(jsonMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", varname)
-		} else if ti2.jmp { // tptr.Implements(jsonMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", varname)
-		} else if ti2.tm { // t.Implements(textMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(%v) ", varname)
-		} else if ti2.tmp { // tptr.Implements(textMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(&%v) ", varname)
+		if t.Implements(jsonMarshalerTyp) {
+			x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
+		} else if tptr.Implements(jsonMarshalerTyp) {
+			x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", genTempVarPfx, mi, varname)
+		} else if t.Implements(textMarshalerTyp) {
+			x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
+		} else if tptr.Implements(textMarshalerTyp) {
+			x.linef("} else if !%sm%s { z.EncTextMarshal(&%v) ", genTempVarPfx, mi, varname)
 		}
 	}
 	x.line("} else {")
@@ -794,12 +763,12 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 	case reflect.Bool:
 		x.line("r.EncodeBool(bool(" + varname + "))")
 	case reflect.String:
-		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", string(" + varname + "))")
+		x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + ", string(" + varname + "))")
 	case reflect.Chan:
-		x.xtraSM(varname, t, true, false)
+		x.xtraSM(varname, true, t)
 		// x.encListFallback(varname, rtid, t)
 	case reflect.Array:
-		x.xtraSM(varname, t, true, true)
+		x.xtraSM(varname, true, t)
 	case reflect.Slice:
 		// if nil, call dedicated function
 		// if a []uint8, call dedicated function
@@ -808,12 +777,12 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 		// - if elements are primitives or Selfers, call dedicated function on each member.
 		// - else call Encoder.encode(XXX) on it.
 		if rtid == uint8SliceTypId {
-			x.line("r.EncodeStringBytes(codecSelferCcRAW" + x.xs + ", []byte(" + varname + "))")
+			x.line("r.EncodeStringBytes(codecSelferC_RAW" + x.xs + ", []byte(" + varname + "))")
 		} else if fastpathAV.index(rtid) != -1 {
 			g := x.newGenV(t)
-			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
+			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", false, e)")
 		} else {
-			x.xtraSM(varname, t, true, false)
+			x.xtraSM(varname, true, t)
 			// x.encListFallback(varname, rtid, t)
 		}
 	case reflect.Map:
@@ -825,9 +794,9 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 		// x.line("if " + varname + " == nil { \nr.EncodeNil()\n } else { ")
 		if fastpathAV.index(rtid) != -1 {
 			g := x.newGenV(t)
-			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
+			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", false, e)")
 		} else {
-			x.xtraSM(varname, t, true, false)
+			x.xtraSM(varname, true, t)
 			// x.encMapFallback(varname, rtid, t)
 		}
 	case reflect.Struct:
@@ -858,53 +827,12 @@ func (x *genRunner) encZero(t reflect.Type) {
 	case reflect.Bool:
 		x.line("r.EncodeBool(false)")
 	case reflect.String:
-		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + `, "")`)
+		x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + `, "")`)
 	default:
 		x.line("r.EncodeNil()")
 	}
 }
 
-func (x *genRunner) encOmitEmptyLine(t2 reflect.StructField, varname string, buf *genBuf) {
-	// smartly check omitEmpty on a struct type, as it may contain uncomparable map/slice/etc.
-	// also, for maps/slices/arrays, check if len ! 0 (not if == zero value)
-	varname2 := varname + "." + t2.Name
-	switch t2.Type.Kind() {
-	case reflect.Struct:
-		rtid2 := rt2id(t2.Type)
-		ti2 := x.ti.get(rtid2, t2.Type)
-		// fmt.Printf(">>>> structfield: omitempty: type: %s, field: %s\n", t2.Type.Name(), t2.Name)
-		if ti2.rtid == timeTypId {
-			buf.s("!(").s(varname2).s(".IsZero())")
-			break
-		}
-		if ti2.isFlag(typeInfoFlagIsZeroerPtr) || ti2.isFlag(typeInfoFlagIsZeroer) {
-			buf.s("!(").s(varname2).s(".IsZero())")
-			break
-		}
-		if ti2.isFlag(typeInfoFlagComparable) {
-			buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
-			break
-		}
-		// buf.s("(")
-		buf.s("false")
-		for i, n := 0, t2.Type.NumField(); i < n; i++ {
-			f := t2.Type.Field(i)
-			if f.PkgPath != "" { // unexported
-				continue
-			}
-			buf.s(" || ")
-			x.encOmitEmptyLine(f, varname2, buf)
-		}
-		//buf.s(")")
-	case reflect.Bool:
-		buf.s(varname2)
-	case reflect.Map, reflect.Slice, reflect.Array, reflect.Chan:
-		buf.s("len(").s(varname2).s(") != 0")
-	default:
-		buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
-	}
-}
-
 func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 	// Use knowledge from structfieldinfo (mbs, encodable fields. Ignore omitempty. )
 	// replicate code in kStruct i.e. for each field, deref type to non-pointer, and call x.enc on it
@@ -919,71 +847,60 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 
 	x.line(sepVarname + " := !z.EncBinary()")
 	x.linef("%s := z.EncBasicHandle().StructToArray", struct2arrvar)
-	x.linef("_, _ = %s, %s", sepVarname, struct2arrvar)
-	x.linef("const %s bool = %v // struct tag has 'toArray'", ti2arrayvar, ti.toArray)
-
-	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
-
-	// var nn int
+	tisfi := ti.sfip // always use sequence from file. decStruct expects same thing.
 	// due to omitEmpty, we need to calculate the
 	// number of non-empty things we write out first.
 	// This is required as we need to pre-determine the size of the container,
 	// to support length-prefixing.
-	if ti.anyOmitEmpty {
-		x.linef("var %s = [%v]bool{ // should field at this index be written?", numfieldsvar, len(tisfi))
-
-		for j, si := range tisfi {
-			_ = j
-			if !si.omitEmpty() {
-				// x.linef("%s[%v] = true // %s", numfieldsvar, j, si.fieldName)
-				x.linef("true, // %s", si.fieldName)
-				// nn++
-				continue
-			}
-			var t2 reflect.StructField
-			var omitline genBuf
-			{
-				t2typ := t
-				varname3 := varname
-				// go through the loop, record the t2 field explicitly,
-				// and gather the omit line if embedded in pointers.
-				for ij, ix := range si.is {
-					if uint8(ij) == si.nis {
-						break
-					}
-					for t2typ.Kind() == reflect.Ptr {
-						t2typ = t2typ.Elem()
-					}
-					t2 = t2typ.Field(int(ix))
-					t2typ = t2.Type
-					varname3 = varname3 + "." + t2.Name
-					// do not include actual field in the omit line.
-					// that is done subsequently (right after - below).
-					if uint8(ij+1) < si.nis && t2typ.Kind() == reflect.Ptr {
-						omitline.s(varname3).s(" != nil && ")
-					}
+	x.linef("var %s [%v]bool", numfieldsvar, len(tisfi))
+	x.linef("_, _, _ = %s, %s, %s", sepVarname, numfieldsvar, struct2arrvar)
+	x.linef("const %s bool = %v", ti2arrayvar, ti.toArray)
+	nn := 0
+	for j, si := range tisfi {
+		if !si.omitEmpty {
+			nn++
+			continue
+		}
+		var t2 reflect.StructField
+		var omitline string
+		if si.i != -1 {
+			t2 = t.Field(int(si.i))
+		} else {
+			t2typ := t
+			varname3 := varname
+			for _, ix := range si.is {
+				for t2typ.Kind() == reflect.Ptr {
+					t2typ = t2typ.Elem()
+				}
+				t2 = t2typ.Field(ix)
+				t2typ = t2.Type
+				varname3 = varname3 + "." + t2.Name
+				if t2typ.Kind() == reflect.Ptr {
+					omitline += varname3 + " != nil && "
 				}
 			}
-			x.encOmitEmptyLine(t2, varname, &omitline)
-			x.linef("%s, // %s", omitline.v(), si.fieldName)
 		}
-		x.line("}")
-		x.linef("_ = %s", numfieldsvar)
+		// never check omitEmpty on a struct type, as it may contain uncomparable map/slice/etc.
+		// also, for maps/slices/arrays, check if len ! 0 (not if == zero value)
+		switch t2.Type.Kind() {
+		case reflect.Struct:
+			omitline += " true"
+		case reflect.Map, reflect.Slice, reflect.Array, reflect.Chan:
+			omitline += "len(" + varname + "." + t2.Name + ") != 0"
+		default:
+			omitline += varname + "." + t2.Name + " != " + x.genZeroValueR(t2.Type)
+		}
+		x.linef("%s[%v] = %s", numfieldsvar, j, omitline)
 	}
-	// x.linef("var %snn%s int", genTempVarPfx, i)
+	x.linef("var %snn%s int", genTempVarPfx, i)
 	x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray {
-	x.linef("r.WriteArrayStart(%d)", len(tisfi))
+	x.line("r.EncodeArrayStart(" + strconv.FormatInt(int64(len(tisfi)), 10) + ")")
 	x.linef("} else {") // if not ti.toArray
-	if ti.anyOmitEmpty {
-		// nn = 0
-		// x.linef("var %snn%s = %v", genTempVarPfx, i, nn)
-		x.linef("var %snn%s int", genTempVarPfx, i)
-		x.linef("for _, b := range %s { if b { %snn%s++ } }", numfieldsvar, genTempVarPfx, i)
-		x.linef("r.WriteMapStart(%snn%s)", genTempVarPfx, i)
-		x.linef("%snn%s = %v", genTempVarPfx, i, 0)
-	} else {
-		x.linef("r.WriteMapStart(%d)", len(tisfi))
-	}
+	x.linef("%snn%s = %v", genTempVarPfx, i, nn)
+	x.linef("for _, b := range %s { if b { %snn%s++ } }", numfieldsvar, genTempVarPfx, i)
+	x.linef("r.EncodeMapStart(%snn%s)", genTempVarPfx, i)
+	x.linef("%snn%s = %v", genTempVarPfx, i, 0)
+	// x.line("r.EncodeMapStart(" + strconv.FormatInt(int64(len(tisfi)), 10) + ")")
 	x.line("}") // close if not StructToArray
 
 	for j, si := range tisfi {
@@ -991,17 +908,17 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 		isNilVarName := genTempVarPfx + "n" + i
 		var labelUsed bool
 		var t2 reflect.StructField
-		{
+		if si.i != -1 {
+			t2 = t.Field(int(si.i))
+		} else {
 			t2typ := t
 			varname3 := varname
-			for ij, ix := range si.is {
-				if uint8(ij) == si.nis {
-					break
-				}
+			for _, ix := range si.is {
+				// fmt.Printf("%%%% %v, ix: %v\n", t2typ, ix)
 				for t2typ.Kind() == reflect.Ptr {
 					t2typ = t2typ.Elem()
 				}
-				t2 = t2typ.Field(int(ix))
+				t2 = t2typ.Field(ix)
 				t2typ = t2.Type
 				varname3 = varname3 + "." + t2.Name
 				if t2typ.Kind() == reflect.Ptr {
@@ -1024,14 +941,14 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 
 		x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray
 		if labelUsed {
-			x.linef("if %s { r.WriteArrayElem(); r.EncodeNil() } else { ", isNilVarName)
+			x.line("if " + isNilVarName + " { r.EncodeNil() } else { ")
 		}
-		x.line("r.WriteArrayElem()")
-		if si.omitEmpty() {
+		x.linef("z.EncSendContainerState(codecSelfer_containerArrayElem%s)", x.xs)
+		if si.omitEmpty {
 			x.linef("if %s[%v] {", numfieldsvar, j)
 		}
 		x.encVar(varname+"."+t2.Name, t2.Type)
-		if si.omitEmpty() {
+		if si.omitEmpty {
 			x.linef("} else {")
 			x.encZero(t2.Type)
 			x.linef("}")
@@ -1042,25 +959,12 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 
 		x.linef("} else {") // if not ti.toArray
 
-		if si.omitEmpty() {
+		if si.omitEmpty {
 			x.linef("if %s[%v] {", numfieldsvar, j)
 		}
-		x.line("r.WriteMapElemKey()")
-
-		// x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", `" + si.encName + "`)")
-		// emulate EncStructFieldKey
-		switch ti.keyType {
-		case valueTypeInt:
-			x.linef("r.EncodeInt(z.M.Int(strconv.ParseInt(`%s`, 10, 64)))", si.encName)
-		case valueTypeUint:
-			x.linef("r.EncodeUint(z.M.Uint(strconv.ParseUint(`%s`, 10, 64)))", si.encName)
-		case valueTypeFloat:
-			x.linef("r.EncodeFloat64(z.M.Float(strconv.ParseFloat(`%s`, 64)))", si.encName)
-		default: // string
-			x.linef("r.EncodeString(codecSelferCcUTF8%s, `%s`)", x.xs, si.encName)
-		}
-		// x.linef("r.EncStructFieldKey(codecSelferValueType%s%s, `%s`)", ti.keyType.String(), x.xs, si.encName)
-		x.line("r.WriteMapElemValue()")
+		x.linef("z.EncSendContainerState(codecSelfer_containerMapKey%s)", x.xs)
+		x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + ", string(\"" + si.encName + "\"))")
+		x.linef("z.EncSendContainerState(codecSelfer_containerMapValue%s)", x.xs)
 		if labelUsed {
 			x.line("if " + isNilVarName + " { r.EncodeNil() } else { ")
 			x.encVar(varname+"."+t2.Name, t2.Type)
@@ -1068,218 +972,136 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 		} else {
 			x.encVar(varname+"."+t2.Name, t2.Type)
 		}
-		if si.omitEmpty() {
+		if si.omitEmpty {
 			x.line("}")
 		}
 		x.linef("} ") // end if/else ti.toArray
 	}
 	x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray {
-	x.line("r.WriteArrayEnd()")
+	x.linef("z.EncSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs)
 	x.line("} else {")
-	x.line("r.WriteMapEnd()")
+	x.linef("z.EncSendContainerState(codecSelfer_containerMapEnd%s)", x.xs)
 	x.line("}")
 
 }
 
 func (x *genRunner) encListFallback(varname string, t reflect.Type) {
-	elemBytes := t.Elem().Kind() == reflect.Uint8
 	if t.AssignableTo(uint8SliceTyp) {
-		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, varname)
+		x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, []byte(%s))", x.xs, varname)
 		return
 	}
-	if t.Kind() == reflect.Array && elemBytes {
-		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, ((*[%d]byte)(%s))[:])", x.xs, t.Len(), varname)
+	if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
+		x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, ([%v]byte(%s))[:])", x.xs, t.Len(), varname)
 		return
 	}
 	i := x.varsfx()
+	g := genTempVarPfx
+	x.line("r.EncodeArrayStart(len(" + varname + "))")
 	if t.Kind() == reflect.Chan {
-		type ts struct {
-			Label, Chan, Slice, Sfx string
-		}
-		tm, err := template.New("").Parse(genEncChanTmpl)
-		if err != nil {
-			panic(err)
-		}
-		x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
-		x.linef("var sch%s []%s", i, x.genTypeName(t.Elem()))
-		err = tm.Execute(x.w, &ts{"Lsch" + i, varname, "sch" + i, i})
-		if err != nil {
-			panic(err)
-		}
-		// x.linef("%s = sch%s", varname, i)
-		if elemBytes {
-			x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, "sch"+i)
-			x.line("}")
-			return
-		}
-		varname = "sch" + i
+		x.linef("for %si%s, %si2%s := 0, len(%s); %si%s < %si2%s; %si%s++ {", g, i, g, i, varname, g, i, g, i, g, i)
+		x.linef("z.EncSendContainerState(codecSelfer_containerArrayElem%s)", x.xs)
+		x.linef("%sv%s := <-%s", g, i, varname)
+	} else {
+		// x.linef("for %si%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname)
+		x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname)
+		x.linef("z.EncSendContainerState(codecSelfer_containerArrayElem%s)", x.xs)
 	}
-
-	x.line("r.WriteArrayStart(len(" + varname + "))")
-	x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname)
-	x.line("r.WriteArrayElem()")
-
 	x.encVar(genTempVarPfx+"v"+i, t.Elem())
 	x.line("}")
-	x.line("r.WriteArrayEnd()")
-	if t.Kind() == reflect.Chan {
-		x.line("}")
-	}
+	x.linef("z.EncSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs)
 }
 
 func (x *genRunner) encMapFallback(varname string, t reflect.Type) {
 	// TODO: expand this to handle canonical.
 	i := x.varsfx()
-	x.line("r.WriteMapStart(len(" + varname + "))")
+	x.line("r.EncodeMapStart(len(" + varname + "))")
 	x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname)
-	x.line("r.WriteMapElemKey()")
+	// x.line("for " + genTempVarPfx + "k" + i + ", " + genTempVarPfx + "v" + i + " := range " + varname + " {")
+	x.linef("z.EncSendContainerState(codecSelfer_containerMapKey%s)", x.xs)
 	x.encVar(genTempVarPfx+"k"+i, t.Key())
-	x.line("r.WriteMapElemValue()")
+	x.linef("z.EncSendContainerState(codecSelfer_containerMapValue%s)", x.xs)
 	x.encVar(genTempVarPfx+"v"+i, t.Elem())
 	x.line("}")
-	x.line("r.WriteMapEnd()")
-}
-
-func (x *genRunner) decVarInitPtr(varname, nilvar string, t reflect.Type, si *structFieldInfo,
-	newbuf, nilbuf *genBuf) (t2 reflect.StructField) {
-	//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
-	// t2 = t.FieldByIndex(si.is)
-	t2typ := t
-	varname3 := varname
-	t2kind := t2typ.Kind()
-	var nilbufed bool
-	if si != nil {
-		for ij, ix := range si.is {
-			if uint8(ij) == si.nis {
-				break
-			}
-			for t2typ.Kind() == reflect.Ptr {
-				t2typ = t2typ.Elem()
-			}
-			t2 = t2typ.Field(int(ix))
-			t2typ = t2.Type
-			varname3 = varname3 + "." + t2.Name
-			t2kind = t2typ.Kind()
-			if t2kind != reflect.Ptr {
-				continue
-			}
-			if newbuf != nil {
-				newbuf.f("if %s == nil { %s = new(%s) }\n", varname3, varname3, x.genTypeName(t2typ.Elem()))
-			}
-			if nilbuf != nil {
-				if !nilbufed {
-					nilbuf.s("if true")
-					nilbufed = true
-				}
-				nilbuf.s(" && ").s(varname3).s(" != nil")
-			}
-		}
-	}
-	// if t2typ.Kind() == reflect.Ptr {
-	// 	varname3 = varname3 + t2.Name
-	// }
-	if nilbuf != nil {
-		if nilbufed {
-			nilbuf.s(" { ")
-		}
-		if nilvar != "" {
-			nilbuf.s(nilvar).s(" = true")
-		} else if tk := t2typ.Kind(); tk == reflect.Ptr {
-			if strings.IndexByte(varname3, '.') != -1 || strings.IndexByte(varname3, '[') != -1 {
-				nilbuf.s(varname3).s(" = nil")
-			} else {
-				nilbuf.s("*").s(varname3).s(" = ").s(x.genZeroValueR(t2typ.Elem()))
-			}
-		} else {
-			nilbuf.s(varname3).s(" = ").s(x.genZeroValueR(t2typ))
-		}
-		if nilbufed {
-			nilbuf.s("}")
-		}
-	}
-	return t2
+	x.linef("z.EncSendContainerState(codecSelfer_containerMapEnd%s)", x.xs)
 }
 
-// decVar takes a variable called varname, of type t
-func (x *genRunner) decVarMain(varname, rand string, t reflect.Type, checkNotNil bool) {
+func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) {
 	// We only encode as nil if a nillable value.
 	// This removes some of the wasted checks for TryDecodeAsNil.
 	// We need to think about this more, to see what happens if omitempty, etc
 	// cause a nil value to be stored when something is expected.
 	// This could happen when decoding from a struct encoded as an array.
 	// For that, decVar should be called with canNil=true, to force true as its value.
-	var varname2 string
-	if t.Kind() != reflect.Ptr {
-		if t.PkgPath() != "" || !x.decTryAssignPrimitive(varname, t, false) {
-			x.dec(varname, t, false)
+	i := x.varsfx()
+	if !canBeNil {
+		canBeNil = genAnythingCanBeNil || !genIsImmutable(t)
+	}
+	if canBeNil {
+		x.line("if r.TryDecodeAsNil() {")
+		if t.Kind() == reflect.Ptr {
+			x.line("if " + varname + " != nil { ")
+
+			// if varname is a field of a struct (has a dot in it),
+			// then just set it to nil
+			if strings.IndexByte(varname, '.') != -1 {
+				x.line(varname + " = nil")
+			} else {
+				x.line("*" + varname + " = " + x.genZeroValueR(t.Elem()))
+			}
+			x.line("}")
+		} else {
+			x.line(varname + " = " + x.genZeroValueR(t))
 		}
+		x.line("} else {")
 	} else {
-		if checkNotNil {
-			x.linef("if %s == nil { %s = new(%s) }", varname, varname, x.genTypeName(t.Elem()))
+		x.line("// cannot be nil")
+	}
+	if t.Kind() != reflect.Ptr {
+		if x.decTryAssignPrimitive(varname, t) {
+			x.line(genTempVarPfx + "v" + i + " := &" + varname)
+			x.dec(genTempVarPfx+"v"+i, t)
 		}
+	} else {
+		x.linef("if %s == nil { %s = new(%s) }", varname, varname, x.genTypeName(t.Elem()))
 		// Ensure we set underlying ptr to a non-nil value (so we can deref to it later).
 		// There's a chance of a **T in here which is nil.
 		var ptrPfx string
 		for t = t.Elem(); t.Kind() == reflect.Ptr; t = t.Elem() {
 			ptrPfx += "*"
-			if checkNotNil {
-				x.linef("if %s%s == nil { %s%s = new(%s)}",
-					ptrPfx, varname, ptrPfx, varname, x.genTypeName(t))
-			}
+			x.linef("if %s%s == nil { %s%s = new(%s)}",
+				ptrPfx, varname, ptrPfx, varname, x.genTypeName(t))
+		}
+		// if varname has [ in it, then create temp variable for this ptr thingie
+		if strings.Index(varname, "[") >= 0 {
+			varname2 := genTempVarPfx + "w" + i
+			x.line(varname2 + " := " + varname)
+			varname = varname2
 		}
-		// Should we create temp var if a slice/map indexing? No. dec(...) can now handle it.
 
 		if ptrPfx == "" {
-			x.dec(varname, t, true)
+			x.dec(varname, t)
 		} else {
-			varname2 = genTempVarPfx + "z" + rand
-			x.line(varname2 + " := " + ptrPfx + varname)
-			x.dec(varname2, t, true)
+			x.line(genTempVarPfx + "z" + i + " := " + ptrPfx + varname)
+			x.dec(genTempVarPfx+"z"+i, t)
 		}
-	}
-}
 
-// decVar takes a variable called varname, of type t
-func (x *genRunner) decVar(varname, nilvar string, t reflect.Type, canBeNil, checkNotNil bool) {
-	i := x.varsfx()
-
-	// We only encode as nil if a nillable value.
-	// This removes some of the wasted checks for TryDecodeAsNil.
-	// We need to think about this more, to see what happens if omitempty, etc
-	// cause a nil value to be stored when something is expected.
-	// This could happen when decoding from a struct encoded as an array.
-	// For that, decVar should be called with canNil=true, to force true as its value.
-
-	if !canBeNil {
-		canBeNil = genAnythingCanBeNil || !genIsImmutable(t)
 	}
 
-	if canBeNil {
-		var buf genBuf
-		x.decVarInitPtr(varname, nilvar, t, nil, nil, &buf)
-		x.linef("if r.TryDecodeAsNil() { %s } else {", buf.buf)
-	} else {
-		x.line("// cannot be nil")
-	}
-
-	x.decVarMain(varname, i, t, checkNotNil)
-
 	if canBeNil {
 		x.line("} ")
 	}
 }
 
-// dec will decode a variable (varname) of type t or ptrTo(t) if isptr==true.
+// dec will decode a variable (varname) of type ptrTo(t).
 // t is always a basetype (i.e. not of kind reflect.Ptr).
-func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
+func (x *genRunner) dec(varname string, t reflect.Type) {
 	// assumptions:
 	//   - the varname is to a pointer already. No need to take address of it
 	//   - t is always a baseType T (not a *T, etc).
-	rtid := rt2id(t)
-	ti2 := x.ti.get(rtid, t)
-	// tptr := reflect.PtrTo(t)
+	rtid := reflect.ValueOf(t).Pointer()
+	tptr := reflect.PtrTo(t)
 	if x.checkForSelfer(t, varname) {
-		if ti2.cs || ti2.csp { // t.Implements(selferTyp) || tptr.Implements(selferTyp) {
+		if t.Implements(selferTyp) || tptr.Implements(selferTyp) {
 			x.line(varname + ".CodecDecodeSelf(d)")
 			return
 		}
@@ -1308,61 +1130,100 @@ func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
 	}
 
 	// check if
-	//   - type is time.Time, Raw, RawExt
+	//   - type is Raw, RawExt
 	//   - the type implements (Text|JSON|Binary)(Unm|M)arshal
-
 	mi := x.varsfx()
-	// x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi)
-	// x.linef("_ = %sm%s", genTempVarPfx, mi)
+	x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi)
+	x.linef("_ = %sm%s", genTempVarPfx, mi)
 	x.line("if false {")           //start if block
 	defer func() { x.line("}") }() //end if block
 
-	var ptrPfx, addrPfx string
-	if isptr {
-		ptrPfx = "*"
-	} else {
-		addrPfx = "&"
-	}
-	if t == timeTyp {
-		x.linef("} else { %s%v = r.DecodeTime()", ptrPfx, varname)
-		return
-	}
 	if t == rawTyp {
-		x.linef("} else { %s%v = z.DecRaw()", ptrPfx, varname)
+		x.linef("} else { *%v = z.DecRaw()", varname)
 		return
 	}
-
 	if t == rawExtTyp {
-		x.linef("} else { r.DecodeExt(%s%v, 0, nil)", addrPfx, varname)
+		x.linef("} else { r.DecodeExt(%v, 0, nil)", varname)
 		return
 	}
 
+	// HACK: Support for Builtins.
+	//       Currently, only Binc supports builtins, and the only builtin type is time.Time.
+	//       Have a method that returns the rtid for time.Time if Handle is Binc.
+	if t == timeTyp {
+		vrtid := genTempVarPfx + "m" + x.varsfx()
+		x.linef("} else if %s := z.TimeRtidIfBinc(); %s != 0 { ", vrtid, vrtid)
+		x.linef("r.DecodeBuiltin(%s, %s)", vrtid, varname)
+	}
 	// only check for extensions if the type is named, and has a packagePath.
-	if !x.nx && genImportPath(t) != "" && t.Name() != "" {
+	if genImportPath(t) != "" && t.Name() != "" {
 		// first check if extensions are configued, before doing the interface conversion
-		// x.linef("} else if z.HasExtensions() && z.DecExt(%s) {", varname)
-		yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
-		x.linef("} else if %s := z.Extension(z.I2Rtid(%s)); %s != nil { z.DecExtension(%s, %s) ", yy, varname, yy, varname, yy)
+		x.linef("} else if z.HasExtensions() && z.DecExt(%s) {", varname)
 	}
 
-	if ti2.bu || ti2.bup { // t.Implements(binaryUnmarshalerTyp) || tptr.Implements(binaryUnmarshalerTyp) {
-		x.linef("} else if z.DecBinary() { z.DecBinaryUnmarshal(%s%v) ", addrPfx, varname)
+	if t.Implements(binaryUnmarshalerTyp) || tptr.Implements(binaryUnmarshalerTyp) {
+		x.linef("} else if %sm%s { z.DecBinaryUnmarshal(%v) ", genTempVarPfx, mi, varname)
 	}
-	if ti2.ju || ti2.jup { // t.Implements(jsonUnmarshalerTyp) || tptr.Implements(jsonUnmarshalerTyp) {
-		x.linef("} else if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(%s%v)", addrPfx, varname)
-	} else if ti2.tu || ti2.tup { // t.Implements(textUnmarshalerTyp) || tptr.Implements(textUnmarshalerTyp) {
-		x.linef("} else if !z.DecBinary() { z.DecTextUnmarshal(%s%v)", addrPfx, varname)
+	if t.Implements(jsonUnmarshalerTyp) || tptr.Implements(jsonUnmarshalerTyp) {
+		x.linef("} else if !%sm%s && z.IsJSONHandle() { z.DecJSONUnmarshal(%v)", genTempVarPfx, mi, varname)
+	} else if t.Implements(textUnmarshalerTyp) || tptr.Implements(textUnmarshalerTyp) {
+		x.linef("} else if !%sm%s { z.DecTextUnmarshal(%v)", genTempVarPfx, mi, varname)
 	}
 
 	x.line("} else {")
 
-	if x.decTryAssignPrimitive(varname, t, isptr) {
-		return
-	}
-
+	// Since these are pointers, we cannot share, and have to use them one by one
 	switch t.Kind() {
+	case reflect.Int:
+		x.line("*((*int)(" + varname + ")) = int(r.DecodeInt(codecSelferBitsize" + x.xs + "))")
+		// x.line("z.DecInt((*int)(" + varname + "))")
+	case reflect.Int8:
+		x.line("*((*int8)(" + varname + ")) = int8(r.DecodeInt(8))")
+		// x.line("z.DecInt8((*int8)(" + varname + "))")
+	case reflect.Int16:
+		x.line("*((*int16)(" + varname + ")) = int16(r.DecodeInt(16))")
+		// x.line("z.DecInt16((*int16)(" + varname + "))")
+	case reflect.Int32:
+		x.line("*((*int32)(" + varname + ")) = int32(r.DecodeInt(32))")
+		// x.line("z.DecInt32((*int32)(" + varname + "))")
+	case reflect.Int64:
+		x.line("*((*int64)(" + varname + ")) = int64(r.DecodeInt(64))")
+		// x.line("z.DecInt64((*int64)(" + varname + "))")
+
+	case reflect.Uint:
+		x.line("*((*uint)(" + varname + ")) = uint(r.DecodeUint(codecSelferBitsize" + x.xs + "))")
+		// x.line("z.DecUint((*uint)(" + varname + "))")
+	case reflect.Uint8:
+		x.line("*((*uint8)(" + varname + ")) = uint8(r.DecodeUint(8))")
+		// x.line("z.DecUint8((*uint8)(" + varname + "))")
+	case reflect.Uint16:
+		x.line("*((*uint16)(" + varname + ")) = uint16(r.DecodeUint(16))")
+		//x.line("z.DecUint16((*uint16)(" + varname + "))")
+	case reflect.Uint32:
+		x.line("*((*uint32)(" + varname + ")) = uint32(r.DecodeUint(32))")
+		//x.line("z.DecUint32((*uint32)(" + varname + "))")
+	case reflect.Uint64:
+		x.line("*((*uint64)(" + varname + ")) = uint64(r.DecodeUint(64))")
+		//x.line("z.DecUint64((*uint64)(" + varname + "))")
+	case reflect.Uintptr:
+		x.line("*((*uintptr)(" + varname + ")) = uintptr(r.DecodeUint(codecSelferBitsize" + x.xs + "))")
+
+	case reflect.Float32:
+		x.line("*((*float32)(" + varname + ")) = float32(r.DecodeFloat(true))")
+		//x.line("z.DecFloat32((*float32)(" + varname + "))")
+	case reflect.Float64:
+		x.line("*((*float64)(" + varname + ")) = float64(r.DecodeFloat(false))")
+		// x.line("z.DecFloat64((*float64)(" + varname + "))")
+
+	case reflect.Bool:
+		x.line("*((*bool)(" + varname + ")) = r.DecodeBool()")
+		// x.line("z.DecBool((*bool)(" + varname + "))")
+	case reflect.String:
+		x.line("*((*string)(" + varname + ")) = r.DecodeString()")
+		// x.line("z.DecString((*string)(" + varname + "))")
 	case reflect.Array, reflect.Chan:
-		x.xtraSM(varname, t, false, isptr)
+		x.xtraSM(varname, false, t)
+		// x.decListFallback(varname, rtid, true, t)
 	case reflect.Slice:
 		// if a []uint8, call dedicated function
 		// if a known fastpath slice, call dedicated function
@@ -1370,13 +1231,12 @@ func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
 		// - if elements are primitives or Selfers, call dedicated function on each member.
 		// - else call Encoder.encode(XXX) on it.
 		if rtid == uint8SliceTypId {
-			x.linef("%s%s = r.DecodeBytes(%s(%s[]byte)(%s), false)",
-				ptrPfx, varname, ptrPfx, ptrPfx, varname)
+			x.line("*" + varname + " = r.DecodeBytes(*(*[]byte)(" + varname + "), false, false)")
 		} else if fastpathAV.index(rtid) != -1 {
 			g := x.newGenV(t)
-			x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
+			x.line("z.F." + g.MethodNamePfx("Dec", false) + "X(" + varname + ", false, d)")
 		} else {
-			x.xtraSM(varname, t, false, isptr)
+			x.xtraSM(varname, false, t)
 			// x.decListFallback(varname, rtid, false, t)
 		}
 	case reflect.Map:
@@ -1386,89 +1246,83 @@ func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
 		// - else call Encoder.encode(XXX) on it.
 		if fastpathAV.index(rtid) != -1 {
 			g := x.newGenV(t)
-			x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
+			x.line("z.F." + g.MethodNamePfx("Dec", false) + "X(" + varname + ", false, d)")
 		} else {
-			x.xtraSM(varname, t, false, isptr)
+			x.xtraSM(varname, false, t)
 			// x.decMapFallback(varname, rtid, t)
 		}
 	case reflect.Struct:
 		if inlist {
-			// no need to create temp variable if isptr, or x.F or x[F]
-			if isptr || strings.IndexByte(varname, '.') != -1 || strings.IndexByte(varname, '[') != -1 {
-				x.decStruct(varname, rtid, t)
-			} else {
-				varname2 := genTempVarPfx + "j" + mi
-				x.line(varname2 + " := &" + varname)
-				x.decStruct(varname2, rtid, t)
-			}
+			x.decStruct(varname, rtid, t)
 		} else {
 			// delete(x.td, rtid)
-			x.line("z.DecFallback(" + addrPfx + varname + ", false)")
+			x.line("z.DecFallback(" + varname + ", false)")
 		}
 	default:
 		if rtidAdded {
 			delete(x.te, rtid)
 		}
-		x.line("z.DecFallback(" + addrPfx + varname + ", true)")
+		x.line("z.DecFallback(" + varname + ", true)")
 	}
 }
 
-func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type, isptr bool) (done bool) {
+func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAsPtr bool) {
 	// This should only be used for exact primitives (ie un-named types).
 	// Named types may be implementations of Selfer, Unmarshaler, etc.
 	// They should be handled by dec(...)
 
-	var ptr string
-	if isptr {
-		ptr = "*"
+	if t.Name() != "" {
+		tryAsPtr = true
+		return
 	}
+
 	switch t.Kind() {
 	case reflect.Int:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
+		x.linef("%s = r.DecodeInt(codecSelferBitsize%s)", varname, x.xs)
 	case reflect.Int8:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 8))", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeInt(8)", varname)
 	case reflect.Int16:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 16))", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeInt(16)", varname)
 	case reflect.Int32:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 32))", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeInt(32)", varname)
 	case reflect.Int64:
-		x.linef("%s%s = (%s)(r.DecodeInt64())", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeInt(64)", varname)
 
 	case reflect.Uint:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
+		x.linef("%s = r.DecodeUint(codecSelferBitsize%s)", varname, x.xs)
 	case reflect.Uint8:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 8))", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeUint(8)", varname)
 	case reflect.Uint16:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 16))", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeUint(16)", varname)
 	case reflect.Uint32:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 32))", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeUint(32)", varname)
 	case reflect.Uint64:
-		x.linef("%s%s = (%s)(r.DecodeUint64())", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeUint(64)", varname)
 	case reflect.Uintptr:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
+		x.linef("%s = r.DecodeUint(codecSelferBitsize%s)", varname, x.xs)
 
 	case reflect.Float32:
-		x.linef("%s%s = (%s)(r.DecodeFloat32As64())", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeFloat(true)", varname)
 	case reflect.Float64:
-		x.linef("%s%s = (%s)(r.DecodeFloat64())", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeFloat(false)", varname)
 
 	case reflect.Bool:
-		x.linef("%s%s = (%s)(r.DecodeBool())", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeBool()", varname)
 	case reflect.String:
-		x.linef("%s%s = (%s)(r.DecodeString())", ptr, varname, x.genTypeName(t))
+		x.linef("%s = r.DecodeString()", varname)
 	default:
-		return false
+		tryAsPtr = true
 	}
-	return true
+	return
 }
 
 func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) {
 	if t.AssignableTo(uint8SliceTyp) {
-		x.line("*" + varname + " = r.DecodeBytes(*((*[]byte)(" + varname + ")), false)")
+		x.line("*" + varname + " = r.DecodeBytes(*((*[]byte)(" + varname + ")), false, false)")
 		return
 	}
 	if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
-		x.linef("r.DecodeBytes( ((*[%d]byte)(%s))[:], true)", t.Len(), varname)
+		x.linef("r.DecodeBytes( ((*[%s]byte)(%s))[:], false, true)", t.Len(), varname)
 		return
 	}
 	type tstruc struct {
@@ -1486,7 +1340,11 @@ func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type
 	funcs := make(template.FuncMap)
 
 	funcs["decLineVar"] = func(varname string) string {
-		x.decVar(varname, "", telem, false, true)
+		x.decVar(varname, telem, false)
+		return ""
+	}
+	funcs["decLine"] = func(pfx string) string {
+		x.decVar(ts.TempVar+pfx+ts.Rand, reflect.PtrTo(telem), false)
 		return ""
 	}
 	funcs["var"] = func(s string) string {
@@ -1544,11 +1402,19 @@ func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type)
 		return telem.Kind() == reflect.Interface
 	}
 	funcs["decLineVarK"] = func(varname string) string {
-		x.decVar(varname, "", tkey, false, true)
+		x.decVar(varname, tkey, false)
 		return ""
 	}
-	funcs["decLineVar"] = func(varname, decodedNilVarname string) string {
-		x.decVar(varname, decodedNilVarname, telem, false, true)
+	funcs["decLineVar"] = func(varname string) string {
+		x.decVar(varname, telem, false)
+		return ""
+	}
+	funcs["decLineK"] = func(pfx string) string {
+		x.decVar(ts.TempVar+pfx+ts.Rand, reflect.PtrTo(tkey), false)
+		return ""
+	}
+	funcs["decLine"] = func(pfx string) string {
+		x.decVar(ts.TempVar+pfx+ts.Rand, reflect.PtrTo(telem), false)
 		return ""
 	}
 	funcs["var"] = func(s string) string {
@@ -1566,17 +1432,31 @@ func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type)
 
 func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintptr, t reflect.Type) {
 	ti := x.ti.get(rtid, t)
-	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
+	tisfi := ti.sfip // always use sequence from file. decStruct expects same thing.
 	x.line("switch (" + kName + ") {")
-	var newbuf, nilbuf genBuf
 	for _, si := range tisfi {
 		x.line("case \"" + si.encName + "\":")
-		newbuf.reset()
-		nilbuf.reset()
-		t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
-		x.linef("if r.TryDecodeAsNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
-		x.decVarMain(varname+"."+t2.Name, x.varsfx(), t2.Type, false)
-		x.line("}")
+		var t2 reflect.StructField
+		if si.i != -1 {
+			t2 = t.Field(int(si.i))
+		} else {
+			//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
+			// t2 = t.FieldByIndex(si.is)
+			t2typ := t
+			varname3 := varname
+			for _, ix := range si.is {
+				for t2typ.Kind() == reflect.Ptr {
+					t2typ = t2typ.Elem()
+				}
+				t2 = t2typ.Field(ix)
+				t2typ = t2.Type
+				varname3 = varname3 + "." + t2.Name
+				if t2typ.Kind() == reflect.Ptr {
+					x.linef("if %s == nil { %s = new(%s) }", varname3, varname3, x.genTypeName(t2typ.Elem()))
+				}
+			}
+		}
+		x.decVar(varname+"."+t2.Name, t2.Type, false)
 	}
 	x.line("default:")
 	// pass the slice here, so that the string will not escape, and maybe save allocation
@@ -1586,10 +1466,27 @@ func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintpt
 
 func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t reflect.Type, style genStructMapStyle) {
 	tpfx := genTempVarPfx
-	ti := x.ti.get(rtid, t)
 	i := x.varsfx()
 	kName := tpfx + "s" + i
 
+	// We thought to use ReadStringAsBytes, as go compiler might optimize the copy out.
+	// However, using that was more expensive, as it seems that the switch expression
+	// is evaluated each time.
+	//
+	// We could depend on decodeString using a temporary/shared buffer internally.
+	// However, this model of creating a byte array, and using explicitly is faster,
+	// and allows optional use of unsafe []byte->string conversion without alloc.
+
+	// Also, ensure that the slice array doesn't escape.
+	// That will help escape analysis prevent allocation when it gets better.
+
+	// x.line("var " + kName + "Arr = [32]byte{} // default string to decode into")
+	// x.line("var " + kName + "Slc = " + kName + "Arr[:] // default slice to decode into")
+	// use the scratch buffer to avoid allocation (most field names are < 32).
+
+	x.line("var " + kName + "Slc = z.DecScratchBuffer() // default slice to decode into")
+
+	x.line("_ = " + kName + "Slc")
 	switch style {
 	case genStructMapStyleLenPrefix:
 		x.linef("for %sj%s := 0; %sj%s < %s; %sj%s++ {", tpfx, i, tpfx, i, lenvarname, tpfx, i)
@@ -1601,49 +1498,60 @@ func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t ref
 		x.linef("if %shl%s { if %sj%s >= %s { break }", tpfx, i, tpfx, i, lenvarname)
 		x.line("} else { if r.CheckBreak() { break }; }")
 	}
-	x.line("r.ReadMapElemKey()")
-
-	// emulate decstructfieldkey
-	switch ti.keyType {
-	case valueTypeInt:
-		x.linef("%s := z.StringView(strconv.AppendInt(z.DecScratchArrayBuffer()[:0], r.DecodeInt64(), 10))", kName)
-	case valueTypeUint:
-		x.linef("%s := z.StringView(strconv.AppendUint(z.DecScratchArrayBuffer()[:0], r.DecodeUint64(), 10))", kName)
-	case valueTypeFloat:
-		x.linef("%s := z.StringView(strconv.AppendFloat(z.DecScratchArrayBuffer()[:0], r.DecodeFloat64(), 'f', -1, 64))", kName)
-	default: // string
-		x.linef("%s := z.StringView(r.DecodeStringAsBytes())", kName)
+	x.linef("z.DecSendContainerState(codecSelfer_containerMapKey%s)", x.xs)
+	x.line(kName + "Slc = r.DecodeBytes(" + kName + "Slc, true, true)")
+	// let string be scoped to this loop alone, so it doesn't escape.
+	if x.unsafe {
+		x.line(kName + "SlcHdr := codecSelferUnsafeString" + x.xs + "{uintptr(unsafe.Pointer(&" +
+			kName + "Slc[0])), len(" + kName + "Slc)}")
+		x.line(kName + " := *(*string)(unsafe.Pointer(&" + kName + "SlcHdr))")
+	} else {
+		x.line(kName + " := string(" + kName + "Slc)")
 	}
-	// x.linef("%s := z.StringView(r.DecStructFieldKey(codecSelferValueType%s%s, z.DecScratchArrayBuffer()))", kName, ti.keyType.String(), x.xs)
-
-	x.line("r.ReadMapElemValue()")
+	x.linef("z.DecSendContainerState(codecSelfer_containerMapValue%s)", x.xs)
 	x.decStructMapSwitch(kName, varname, rtid, t)
 
 	x.line("} // end for " + tpfx + "j" + i)
-	x.line("r.ReadMapEnd()")
+	x.linef("z.DecSendContainerState(codecSelfer_containerMapEnd%s)", x.xs)
 }
 
 func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid uintptr, t reflect.Type) {
 	tpfx := genTempVarPfx
 	i := x.varsfx()
 	ti := x.ti.get(rtid, t)
-	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
+	tisfi := ti.sfip // always use sequence from file. decStruct expects same thing.
 	x.linef("var %sj%s int", tpfx, i)
 	x.linef("var %sb%s bool", tpfx, i)                        // break
 	x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
-	var newbuf, nilbuf genBuf
 	for _, si := range tisfi {
+		var t2 reflect.StructField
+		if si.i != -1 {
+			t2 = t.Field(int(si.i))
+		} else {
+			//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
+			// t2 = t.FieldByIndex(si.is)
+			t2typ := t
+			varname3 := varname
+			for _, ix := range si.is {
+				for t2typ.Kind() == reflect.Ptr {
+					t2typ = t2typ.Elem()
+				}
+				t2 = t2typ.Field(ix)
+				t2typ = t2.Type
+				varname3 = varname3 + "." + t2.Name
+				if t2typ.Kind() == reflect.Ptr {
+					x.linef("if %s == nil { %s = new(%s) }", varname3, varname3, x.genTypeName(t2typ.Elem()))
+				}
+			}
+		}
+
 		x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = r.CheckBreak() }",
 			tpfx, i, tpfx, i, tpfx, i,
 			tpfx, i, lenvarname, tpfx, i)
-		x.linef("if %sb%s { r.ReadArrayEnd(); %s }", tpfx, i, breakString)
-		x.line("r.ReadArrayElem()")
-		newbuf.reset()
-		nilbuf.reset()
-		t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
-		x.linef("if r.TryDecodeAsNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
-		x.decVarMain(varname+"."+t2.Name, x.varsfx(), t2.Type, false)
-		x.line("}")
+		x.linef("if %sb%s { z.DecSendContainerState(codecSelfer_containerArrayEnd%s); %s }",
+			tpfx, i, x.xs, breakString)
+		x.linef("z.DecSendContainerState(codecSelfer_containerArrayElem%s)", x.xs)
+		x.decVar(varname+"."+t2.Name, t2.Type, true)
 	}
 	// read remaining values and throw away.
 	x.line("for {")
@@ -1651,28 +1559,28 @@ func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid
 		tpfx, i, tpfx, i, tpfx, i,
 		tpfx, i, lenvarname, tpfx, i)
 	x.linef("if %sb%s { break }", tpfx, i)
-	x.line("r.ReadArrayElem()")
+	x.linef("z.DecSendContainerState(codecSelfer_containerArrayElem%s)", x.xs)
 	x.linef(`z.DecStructFieldNotFound(%sj%s - 1, "")`, tpfx, i)
 	x.line("}")
-	x.line("r.ReadArrayEnd()")
+	x.linef("z.DecSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs)
 }
 
 func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) {
-	// varname MUST be a ptr, or a struct field or a slice element.
+	// if container is map
 	i := x.varsfx()
 	x.linef("%sct%s := r.ContainerType()", genTempVarPfx, i)
 	x.linef("if %sct%s == codecSelferValueTypeMap%s {", genTempVarPfx, i, x.xs)
 	x.line(genTempVarPfx + "l" + i + " := r.ReadMapStart()")
 	x.linef("if %sl%s == 0 {", genTempVarPfx, i)
-	x.line("r.ReadMapEnd()")
+	x.linef("z.DecSendContainerState(codecSelfer_containerMapEnd%s)", x.xs)
 	if genUseOneFunctionForDecStructMap {
 		x.line("} else { ")
-		x.linef("%s.codecDecodeSelfFromMap(%sl%s, d)", varname, genTempVarPfx, i)
+		x.linef("x.codecDecodeSelfFromMap(%sl%s, d)", genTempVarPfx, i)
 	} else {
 		x.line("} else if " + genTempVarPfx + "l" + i + " > 0 { ")
-		x.line(varname + ".codecDecodeSelfFromMapLenPrefix(" + genTempVarPfx + "l" + i + ", d)")
+		x.line("x.codecDecodeSelfFromMapLenPrefix(" + genTempVarPfx + "l" + i + ", d)")
 		x.line("} else {")
-		x.line(varname + ".codecDecodeSelfFromMapCheckBreak(" + genTempVarPfx + "l" + i + ", d)")
+		x.line("x.codecDecodeSelfFromMapCheckBreak(" + genTempVarPfx + "l" + i + ", d)")
 	}
 	x.line("}")
 
@@ -1680,13 +1588,13 @@ func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) {
 	x.linef("} else if %sct%s == codecSelferValueTypeArray%s {", genTempVarPfx, i, x.xs)
 	x.line(genTempVarPfx + "l" + i + " := r.ReadArrayStart()")
 	x.linef("if %sl%s == 0 {", genTempVarPfx, i)
-	x.line("r.ReadArrayEnd()")
+	x.linef("z.DecSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs)
 	x.line("} else { ")
-	x.linef("%s.codecDecodeSelfFromArray(%sl%s, d)", varname, genTempVarPfx, i)
+	x.linef("x.codecDecodeSelfFromArray(%sl%s, d)", genTempVarPfx, i)
 	x.line("}")
 	// else panic
 	x.line("} else { ")
-	x.line("panic(errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + ")")
+	x.line("panic(codecSelferOnlyMapOrArrayEncodeToStructErr" + x.xs + ")")
 	x.line("} ")
 }
 
@@ -1745,8 +1653,15 @@ func (x *genV) MethodNamePfx(prefix string, prim bool) string {
 func genImportPath(t reflect.Type) (s string) {
 	s = t.PkgPath()
 	if genCheckVendor {
-		// HACK: always handle vendoring. It should be typically on in go 1.6, 1.7
-		s = genStripVendor(s)
+		// HACK: Misbehaviour occurs in go 1.5. May have to re-visit this later.
+		// if s contains /vendor/ OR startsWith vendor/, then return everything after it.
+		const vendorStart = "vendor/"
+		const vendorInline = "/vendor/"
+		if i := strings.LastIndex(s, vendorInline); i >= 0 {
+			s = s[i+len(vendorInline):]
+		} else if strings.HasPrefix(s, vendorStart) {
+			s = s[len(vendorStart):]
+		}
 	}
 	return
 }
@@ -1868,13 +1783,13 @@ func genIsImmutable(t reflect.Type) (v bool) {
 }
 
 type genInternal struct {
-	Version int
-	Values  []genV
+	Values []genV
+	Unsafe bool
 }
 
 func (x genInternal) FastpathLen() (l int) {
 	for _, v := range x.Values {
-		if v.Primitive == "" && !(v.MapKey == "" && v.Elem == "uint8") {
+		if v.Primitive == "" {
 			l++
 		}
 	}
@@ -1894,32 +1809,6 @@ func genInternalZeroValue(s string) string {
 	}
 }
 
-var genInternalNonZeroValueIdx [5]uint64
-var genInternalNonZeroValueStrs = [2][5]string{
-	{`"string-is-an-interface"`, "true", `"some-string"`, "11.1", "33"},
-	{`"string-is-an-interface-2"`, "true", `"some-string-2"`, "22.2", "44"},
-}
-
-func genInternalNonZeroValue(s string) string {
-	switch s {
-	case "interface{}", "interface {}":
-		genInternalNonZeroValueIdx[0]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[0]%2][0] // return string, to remove ambiguity
-	case "bool":
-		genInternalNonZeroValueIdx[1]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[1]%2][1]
-	case "string":
-		genInternalNonZeroValueIdx[2]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[2]%2][2]
-	case "float32", "float64", "float", "double":
-		genInternalNonZeroValueIdx[3]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[3]%2][3]
-	default:
-		genInternalNonZeroValueIdx[4]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[4]%2][4]
-	}
-}
-
 func genInternalEncCommandAsString(s string, vname string) string {
 	switch s {
 	case "uint", "uint8", "uint16", "uint32", "uint64":
@@ -1927,15 +1816,15 @@ func genInternalEncCommandAsString(s string, vname string) string {
 	case "int", "int8", "int16", "int32", "int64":
 		return "ee.EncodeInt(int64(" + vname + "))"
 	case "string":
-		return "ee.EncodeString(cUTF8, " + vname + ")"
+		return "ee.EncodeString(c_UTF8, " + vname + ")"
 	case "float32":
 		return "ee.EncodeFloat32(" + vname + ")"
 	case "float64":
 		return "ee.EncodeFloat64(" + vname + ")"
 	case "bool":
 		return "ee.EncodeBool(" + vname + ")"
-	// case "symbol":
-	// 	return "ee.EncodeSymbol(" + vname + ")"
+	case "symbol":
+		return "ee.EncodeSymbol(" + vname + ")"
 	default:
 		return "e.encode(" + vname + ")"
 	}
@@ -1944,34 +1833,34 @@ func genInternalEncCommandAsString(s string, vname string) string {
 func genInternalDecCommandAsString(s string) string {
 	switch s {
 	case "uint":
-		return "uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))"
+		return "uint(dd.DecodeUint(uintBitsize))"
 	case "uint8":
-		return "uint8(chkOvf.UintV(dd.DecodeUint64(), 8))"
+		return "uint8(dd.DecodeUint(8))"
 	case "uint16":
-		return "uint16(chkOvf.UintV(dd.DecodeUint64(), 16))"
+		return "uint16(dd.DecodeUint(16))"
 	case "uint32":
-		return "uint32(chkOvf.UintV(dd.DecodeUint64(), 32))"
+		return "uint32(dd.DecodeUint(32))"
 	case "uint64":
-		return "dd.DecodeUint64()"
+		return "dd.DecodeUint(64)"
 	case "uintptr":
-		return "uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))"
+		return "uintptr(dd.DecodeUint(uintBitsize))"
 	case "int":
-		return "int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))"
+		return "int(dd.DecodeInt(intBitsize))"
 	case "int8":
-		return "int8(chkOvf.IntV(dd.DecodeInt64(), 8))"
+		return "int8(dd.DecodeInt(8))"
 	case "int16":
-		return "int16(chkOvf.IntV(dd.DecodeInt64(), 16))"
+		return "int16(dd.DecodeInt(16))"
 	case "int32":
-		return "int32(chkOvf.IntV(dd.DecodeInt64(), 32))"
+		return "int32(dd.DecodeInt(32))"
 	case "int64":
-		return "dd.DecodeInt64()"
+		return "dd.DecodeInt(64)"
 
 	case "string":
 		return "dd.DecodeString()"
 	case "float32":
-		return "float32(chkOvf.Float32V(dd.DecodeFloat64()))"
+		return "float32(dd.DecodeFloat(true))"
 	case "float64":
-		return "dd.DecodeFloat64()"
+		return "dd.DecodeFloat(false)"
 	case "bool":
 		return "dd.DecodeBool()"
 	default:
@@ -1995,21 +1884,8 @@ func genInternalSortType(s string, elem bool) string {
 	panic("sorttype: unexpected type: " + s)
 }
 
-func genStripVendor(s string) string {
-	// HACK: Misbehaviour occurs in go 1.5. May have to re-visit this later.
-	// if s contains /vendor/ OR startsWith vendor/, then return everything after it.
-	const vendorStart = "vendor/"
-	const vendorInline = "/vendor/"
-	if i := strings.LastIndex(s, vendorInline); i >= 0 {
-		s = s[i+len(vendorInline):]
-	} else if strings.HasPrefix(s, vendorStart) {
-		s = s[len(vendorStart):]
-	}
-	return s
-}
-
 // var genInternalMu sync.Mutex
-var genInternalV = genInternal{Version: genVersion}
+var genInternalV genInternal
 var genInternalTmplFuncs template.FuncMap
 var genInternalOnce sync.Once
 
@@ -2072,15 +1948,14 @@ func genInternalInit() {
 		"float64":     8,
 		"bool":        1,
 	}
-	var gt = genInternal{Version: genVersion}
+	var gt genInternal
 
 	// For each slice or map type, there must be a (symmetrical) Encode and Decode fast-path function
 	for _, s := range types {
 		gt.Values = append(gt.Values, genV{Primitive: s, Size: mapvaltypes2[s]})
-		// if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already.
-		// 	gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]})
-		// }
-		gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]})
+		if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already.
+			gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]})
+		}
 		if _, ok := mapvaltypes2[s]; !ok {
 			gt.Values = append(gt.Values, genV{MapKey: s, Elem: s, Size: 2 * mapvaltypes2[s]})
 		}
@@ -2094,7 +1969,6 @@ func genInternalInit() {
 	funcs["encmd"] = genInternalEncCommandAsString
 	funcs["decmd"] = genInternalDecCommandAsString
 	funcs["zerocmd"] = genInternalZeroValue
-	funcs["nonzerocmd"] = genInternalNonZeroValue
 	funcs["hasprefix"] = strings.HasPrefix
 	funcs["sorttype"] = genInternalSortType
 
@@ -2106,10 +1980,11 @@ func genInternalInit() {
 // It is run by the program author alone.
 // Unfortunately, it has to be exported so that it can be called from a command line tool.
 // *** DO NOT USE ***
-func genInternalGoFile(r io.Reader, w io.Writer) (err error) {
+func genInternalGoFile(r io.Reader, w io.Writer, safe bool) (err error) {
 	genInternalOnce.Do(genInternalInit)
 
 	gt := genInternalV
+	gt.Unsafe = !safe
 
 	t := template.New("").Funcs(genInternalTmplFuncs)
 
diff --git a/vendor/github.com/ugorji/go/codec/gen_15.go b/vendor/github.com/ugorji/go/codec/gen_15.go
new file mode 100644
index 000000000..ab76c3102
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen_15.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.5,!go1.6
+
+package codec
+
+import "os"
+
+func init() {
+	genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1"
+}
diff --git a/vendor/github.com/ugorji/go/codec/gen_16.go b/vendor/github.com/ugorji/go/codec/gen_16.go
new file mode 100644
index 000000000..87c04e2e1
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen_16.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.6
+
+package codec
+
+import "os"
+
+func init() {
+	genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") != "0"
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go b/vendor/github.com/ugorji/go/codec/gen_17.go
similarity index 53%
rename from vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
rename to vendor/github.com/ugorji/go/codec/gen_17.go
index c5b815505..3881a43ce 100644
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
+++ b/vendor/github.com/ugorji/go/codec/gen_17.go
@@ -1,8 +1,10 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 // +build go1.7
 
 package codec
 
-const genCheckVendor = true
+func init() {
+	genCheckVendor = true
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go b/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
deleted file mode 100644
index 9ddbe2059..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.5
-
-package codec
-
-import "reflect"
-
-const reflectArrayOfSupported = true
-
-func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
-	return reflect.ArrayOf(count, elem)
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go b/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
deleted file mode 100644
index c5fcd6697..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.5
-
-package codec
-
-import "reflect"
-
-const reflectArrayOfSupported = false
-
-func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
-	panic("codec: reflect.ArrayOf unsupported in this go version")
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go b/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
deleted file mode 100644
index bc39d6b71..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.9
-
-package codec
-
-import "reflect"
-
-func makeMapReflect(t reflect.Type, size int) reflect.Value {
-	if size < 0 {
-		return reflect.MakeMapWithSize(t, 4)
-	}
-	return reflect.MakeMapWithSize(t, size)
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go b/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
deleted file mode 100644
index cde4cd372..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.9
-
-package codec
-
-import "reflect"
-
-func makeMapReflect(t reflect.Type, size int) reflect.Value {
-	return reflect.MakeMap(t)
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
deleted file mode 100644
index 794133a3c..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.10
-
-package codec
-
-const allowSetUnexportedEmbeddedPtr = false
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
deleted file mode 100644
index fd92ede35..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.10
-
-package codec
-
-const allowSetUnexportedEmbeddedPtr = true
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go b/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
deleted file mode 100644
index 8debfa613..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.4
-
-package codec
-
-// This codec package will only work for go1.4 and above.
-// This is for the following reasons:
-//   - go 1.4 was released in 2014
-//   - go runtime is written fully in go
-//   - interface only holds pointers
-//   - reflect.Value is stabilized as 3 words
-
-func init() {
-	panic("codec: go 1.3 and below are not supported")
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
deleted file mode 100644
index 0f1bb01e5..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.5,!go1.6
-
-package codec
-
-import "os"
-
-var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1"
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
deleted file mode 100644
index 2fb4b057d..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.6,!go1.7
-
-package codec
-
-import "os"
-
-var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") != "0"
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
deleted file mode 100644
index 837cf240b..000000000
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.5
-
-package codec
-
-var genCheckVendor = false
diff --git a/vendor/github.com/ugorji/go/codec/helper.go b/vendor/github.com/ugorji/go/codec/helper.go
index bd29895b6..8b94fc1e4 100644
--- a/vendor/github.com/ugorji/go/codec/helper.go
+++ b/vendor/github.com/ugorji/go/codec/helper.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
@@ -102,11 +102,9 @@ import (
 	"encoding/binary"
 	"errors"
 	"fmt"
-	"io"
 	"math"
 	"reflect"
 	"sort"
-	"strconv"
 	"strings"
 	"sync"
 	"time"
@@ -114,28 +112,32 @@ import (
 
 const (
 	scratchByteArrayLen = 32
-	// initCollectionCap   = 16 // 32 is defensive. 16 is preferred.
+	initCollectionCap   = 32 // 32 is defensive. 16 is preferred.
 
 	// Support encoding.(Binary|Text)(Unm|M)arshaler.
 	// This constant flag will enable or disable it.
 	supportMarshalInterfaces = true
 
+	// Each Encoder or Decoder uses a cache of functions based on conditionals,
+	// so that the conditionals are not run every time.
+	//
+	// Either a map or a slice is used to keep track of the functions.
+	// The map is more natural, but has a higher cost than a slice/array.
+	// This flag (useMapForCodecCache) controls which is used.
+	//
+	// From benchmarks, slices with linear search perform better with < 32 entries.
+	// We have typically seen a high threshold of about 24 entries.
+	useMapForCodecCache = false
+
 	// for debugging, set this to false, to catch panic traces.
 	// Note that this will always cause rpc tests to fail, since they need io.EOF sent via panic.
 	recoverPanicToErr = true
 
-	// arrayCacheLen is the length of the cache used in encoder or decoder for
-	// allowing zero-alloc initialization.
-	arrayCacheLen = 8
-
-	// size of the cacheline: defaulting to value for archs: amd64, arm64, 386
-	// should use "runtime/internal/sys".CacheLineSize, but that is not exposed.
-	cacheLineSize = 64
-
-	wordSizeBits = 32 << (^uint(0) >> 63) // strconv.IntSize
-	wordSize     = wordSizeBits / 8
-
-	maxLevelsEmbedding = 15 // use this, so structFieldInfo fits into 8 bytes
+	// if resetSliceElemToZeroValue, then on decoding a slice, reset the element to a zero value first.
+	// Only concern is that, if the slice already contained some garbage, we will decode into that garbage.
+	// The chances of this are slim, so leave this "optimization".
+	// TODO: should this be true, to ensure that we always decode into a "zero" "empty" value?
+	resetSliceElemToZeroValue bool = false
 )
 
 var (
@@ -143,28 +145,15 @@ var (
 	zeroByteSlice = oneByteArr[:0:0]
 )
 
-var refBitset bitset32
-var pool pooler
-var panicv panicHdl
-
-func init() {
-	pool.init()
-
-	refBitset.set(byte(reflect.Map))
-	refBitset.set(byte(reflect.Ptr))
-	refBitset.set(byte(reflect.Func))
-	refBitset.set(byte(reflect.Chan))
-}
-
 type charEncoding uint8
 
 const (
-	cRAW charEncoding = iota
-	cUTF8
-	cUTF16LE
-	cUTF16BE
-	cUTF32LE
-	cUTF32BE
+	c_RAW charEncoding = iota
+	c_UTF8
+	c_UTF16LE
+	c_UTF16BE
+	c_UTF32LE
+	c_UTF32BE
 )
 
 // valueType is the stream type
@@ -182,35 +171,12 @@ const (
 	valueTypeBytes
 	valueTypeMap
 	valueTypeArray
-	valueTypeTime
+	valueTypeTimestamp
 	valueTypeExt
 
 	// valueTypeInvalid = 0xff
 )
 
-var valueTypeStrings = [...]string{
-	"Unset",
-	"Nil",
-	"Int",
-	"Uint",
-	"Float",
-	"Bool",
-	"String",
-	"Symbol",
-	"Bytes",
-	"Map",
-	"Array",
-	"Timestamp",
-	"Ext",
-}
-
-func (x valueType) String() string {
-	if int(x) < len(valueTypeStrings) {
-		return valueTypeStrings[x]
-	}
-	return strconv.FormatInt(int64(x), 10)
-}
-
 type seqType uint8
 
 const (
@@ -236,11 +202,11 @@ const (
 	containerArrayEnd
 )
 
-// // sfiIdx used for tracking where a (field/enc)Name is seen in a []*structFieldInfo
-// type sfiIdx struct {
-// 	name  string
-// 	index int
-// }
+// sfiIdx used for tracking where a (field/enc)Name is seen in a []*structFieldInfo
+type sfiIdx struct {
+	name  string
+	index int
+}
 
 // do not recurse if a containing type refers to an embedded type
 // which refers back to its containing type (via a pointer).
@@ -249,39 +215,34 @@ const (
 const rgetMaxRecursion = 2
 
 // Anecdotally, we believe most types have <= 12 fields.
-// - even Java's PMD rules set TooManyFields threshold to 15.
-// However, go has embedded fields, which should be regarded as
-// top level, allowing structs to possibly double or triple.
-// In addition, we don't want to keep creating transient arrays,
-// especially for the sfi index tracking, and the evtypes tracking.
-//
-// So - try to keep typeInfoLoadArray within 2K bytes
-const (
-	typeInfoLoadArraySfisLen   = 16
-	typeInfoLoadArraySfiidxLen = 8 * 112
-	typeInfoLoadArrayEtypesLen = 12
-	typeInfoLoadArrayBLen      = 8 * 4
-)
+// Java's PMD rules set TooManyFields threshold to 15.
+const rgetPoolTArrayLen = 12
+
+type rgetT struct {
+	fNames   []string
+	encNames []string
+	etypes   []uintptr
+	sfis     []*structFieldInfo
+}
+
+type rgetPoolT struct {
+	fNames   [rgetPoolTArrayLen]string
+	encNames [rgetPoolTArrayLen]string
+	etypes   [rgetPoolTArrayLen]uintptr
+	sfis     [rgetPoolTArrayLen]*structFieldInfo
+	sfiidx   [rgetPoolTArrayLen]sfiIdx
+}
 
-type typeInfoLoad struct {
-	// fNames   []string
-	// encNames []string
-	etypes []uintptr
-	sfis   []structFieldInfo
+var rgetPool = sync.Pool{
+	New: func() interface{} { return new(rgetPoolT) },
 }
 
-type typeInfoLoadArray struct {
-	// fNames   [typeInfoLoadArrayLen]string
-	// encNames [typeInfoLoadArrayLen]string
-	sfis   [typeInfoLoadArraySfisLen]structFieldInfo
-	sfiidx [typeInfoLoadArraySfiidxLen]byte
-	etypes [typeInfoLoadArrayEtypesLen]uintptr
-	b      [typeInfoLoadArrayBLen]byte // scratch - used for struct field names
+type containerStateRecv interface {
+	sendContainerState(containerState)
 }
 
 // mirror json.Marshaler and json.Unmarshaler here,
 // so we don't import the encoding/json package
-
 type jsonMarshaler interface {
 	MarshalJSON() ([]byte, error)
 }
@@ -289,12 +250,6 @@ type jsonUnmarshaler interface {
 	UnmarshalJSON([]byte) error
 }
 
-type isZeroer interface {
-	IsZero() bool
-}
-
-// type byteAccepter func(byte) bool
-
 var (
 	bigen               = binary.BigEndian
 	structInfoFieldName = "_struct"
@@ -304,17 +259,11 @@ var (
 	intfSliceTyp   = reflect.TypeOf([]interface{}(nil))
 	intfTyp        = intfSliceTyp.Elem()
 
-	reflectValTyp = reflect.TypeOf((*reflect.Value)(nil)).Elem()
-
 	stringTyp     = reflect.TypeOf("")
 	timeTyp       = reflect.TypeOf(time.Time{})
 	rawExtTyp     = reflect.TypeOf(RawExt{})
 	rawTyp        = reflect.TypeOf(Raw{})
-	uintptrTyp    = reflect.TypeOf(uintptr(0))
-	uint8Typ      = reflect.TypeOf(uint8(0))
 	uint8SliceTyp = reflect.TypeOf([]uint8(nil))
-	uintTyp       = reflect.TypeOf(uint(0))
-	intTyp        = reflect.TypeOf(int(0))
 
 	mapBySliceTyp = reflect.TypeOf((*MapBySlice)(nil)).Elem()
 
@@ -328,130 +277,65 @@ var (
 	jsonUnmarshalerTyp = reflect.TypeOf((*jsonUnmarshaler)(nil)).Elem()
 
 	selferTyp = reflect.TypeOf((*Selfer)(nil)).Elem()
-	iszeroTyp = reflect.TypeOf((*isZeroer)(nil)).Elem()
 
-	uint8TypId      = rt2id(uint8Typ)
-	uint8SliceTypId = rt2id(uint8SliceTyp)
-	rawExtTypId     = rt2id(rawExtTyp)
-	rawTypId        = rt2id(rawTyp)
-	intfTypId       = rt2id(intfTyp)
-	timeTypId       = rt2id(timeTyp)
-	stringTypId     = rt2id(stringTyp)
+	uint8SliceTypId = reflect.ValueOf(uint8SliceTyp).Pointer()
+	rawExtTypId     = reflect.ValueOf(rawExtTyp).Pointer()
+	rawTypId        = reflect.ValueOf(rawTyp).Pointer()
+	intfTypId       = reflect.ValueOf(intfTyp).Pointer()
+	timeTypId       = reflect.ValueOf(timeTyp).Pointer()
+	stringTypId     = reflect.ValueOf(stringTyp).Pointer()
 
-	mapStrIntfTypId  = rt2id(mapStrIntfTyp)
-	mapIntfIntfTypId = rt2id(mapIntfIntfTyp)
-	intfSliceTypId   = rt2id(intfSliceTyp)
-	// mapBySliceTypId  = rt2id(mapBySliceTyp)
+	mapStrIntfTypId  = reflect.ValueOf(mapStrIntfTyp).Pointer()
+	mapIntfIntfTypId = reflect.ValueOf(mapIntfIntfTyp).Pointer()
+	intfSliceTypId   = reflect.ValueOf(intfSliceTyp).Pointer()
+	// mapBySliceTypId  = reflect.ValueOf(mapBySliceTyp).Pointer()
 
-	intBitsize  = uint8(intTyp.Bits())
-	uintBitsize = uint8(uintTyp.Bits())
+	intBitsize  uint8 = uint8(reflect.TypeOf(int(0)).Bits())
+	uintBitsize uint8 = uint8(reflect.TypeOf(uint(0)).Bits())
 
 	bsAll0x00 = []byte{0, 0, 0, 0, 0, 0, 0, 0}
 	bsAll0xff = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
 
 	chkOvf checkOverflow
 
-	errNoFieldNameToStructFieldInfo = errors.New("no field name passed to parseStructFieldInfo")
+	noFieldNameToStructFieldInfoErr = errors.New("no field name passed to parseStructFieldInfo")
 )
 
 var defTypeInfos = NewTypeInfos([]string{"codec", "json"})
 
-var immutableKindsSet = [32]bool{
-	// reflect.Invalid:  ,
-	reflect.Bool:       true,
-	reflect.Int:        true,
-	reflect.Int8:       true,
-	reflect.Int16:      true,
-	reflect.Int32:      true,
-	reflect.Int64:      true,
-	reflect.Uint:       true,
-	reflect.Uint8:      true,
-	reflect.Uint16:     true,
-	reflect.Uint32:     true,
-	reflect.Uint64:     true,
-	reflect.Uintptr:    true,
-	reflect.Float32:    true,
-	reflect.Float64:    true,
-	reflect.Complex64:  true,
-	reflect.Complex128: true,
-	// reflect.Array
-	// reflect.Chan
-	// reflect.Func: true,
-	// reflect.Interface
-	// reflect.Map
-	// reflect.Ptr
-	// reflect.Slice
-	reflect.String: true,
-	// reflect.Struct
-	// reflect.UnsafePointer
-}
-
 // Selfer defines methods by which a value can encode or decode itself.
 //
 // Any type which implements Selfer will be able to encode or decode itself.
 // Consequently, during (en|de)code, this takes precedence over
 // (text|binary)(M|Unm)arshal or extension support.
-//
-// Note: *the first set of bytes of any value MUST NOT represent nil in the format*.
-// This is because, during each decode, we first check the the next set of bytes
-// represent nil, and if so, we just set the value to nil.
 type Selfer interface {
 	CodecEncodeSelf(*Encoder)
 	CodecDecodeSelf(*Decoder)
 }
 
-// MapBySlice is a tag interface that denotes wrapped slice should encode as a map in the stream.
+// MapBySlice represents a slice which should be encoded as a map in the stream.
 // The slice contains a sequence of key-value pairs.
 // This affords storing a map in a specific sequence in the stream.
 //
-// Example usage:
-//    type T1 []string         // or []int or []Point or any other "slice" type
-//    func (_ T1) MapBySlice{} // T1 now implements MapBySlice, and will be encoded as a map
-//    type T2 struct { KeyValues T1 }
-//
-//    var kvs = []string{"one", "1", "two", "2", "three", "3"}
-//    var v2 = T2{ KeyValues: T1(kvs) }
-//    // v2 will be encoded like the map: {"KeyValues": {"one": "1", "two": "2", "three": "3"} }
-//
 // The support of MapBySlice affords the following:
 //   - A slice type which implements MapBySlice will be encoded as a map
 //   - A slice can be decoded from a map in the stream
-//   - It MUST be a slice type (not a pointer receiver) that implements MapBySlice
 type MapBySlice interface {
 	MapBySlice()
 }
 
-// BasicHandle encapsulates the common options and extension functions.
+// WARNING: DO NOT USE DIRECTLY. EXPORTED FOR GODOC BENEFIT. WILL BE REMOVED.
 //
-// Deprecated: DO NOT USE DIRECTLY. EXPORTED FOR GODOC BENEFIT. WILL BE REMOVED.
+// BasicHandle encapsulates the common options and extension functions.
 type BasicHandle struct {
-	// BasicHandle is always a part of a different type.
-	// It doesn't have to fit into it own cache lines.
-
 	// TypeInfos is used to get the type info for any type.
 	//
 	// If not configured, the default TypeInfos is used, which uses struct tag keys: codec, json
 	TypeInfos *TypeInfos
 
-	// Note: BasicHandle is not comparable, due to these slices here (extHandle, intf2impls).
-	// If *[]T is used instead, this becomes comparable, at the cost of extra indirection.
-	// Thses slices are used all the time, so keep as slices (not pointers).
-
 	extHandle
-
-	intf2impls
-
-	RPCOptions
-
-	// ---- cache line
-
-	DecodeOptions
-
-	// ---- cache line
-
 	EncodeOptions
-
-	// noBuiltInTypeChecker
+	DecodeOptions
 }
 
 func (x *BasicHandle) getBasicHandle() *BasicHandle {
@@ -459,10 +343,10 @@ func (x *BasicHandle) getBasicHandle() *BasicHandle {
 }
 
 func (x *BasicHandle) getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
-	if x.TypeInfos == nil {
-		return defTypeInfos.get(rtid, rt)
+	if x.TypeInfos != nil {
+		return x.TypeInfos.get(rtid, rt)
 	}
-	return x.TypeInfos.get(rtid, rt)
+	return defTypeInfos.get(rtid, rt)
 }
 
 // Handle is the interface for a specific encoding format.
@@ -471,36 +355,28 @@ func (x *BasicHandle) getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo)
 // and not modified while in use. Such a pre-configured Handle
 // is safe for concurrent access.
 type Handle interface {
-	Name() string
 	getBasicHandle() *BasicHandle
-	recreateEncDriver(encDriver) bool
 	newEncDriver(w *Encoder) encDriver
 	newDecDriver(r *Decoder) decDriver
 	isBinary() bool
-	hasElemSeparators() bool
-	// IsBuiltinType(rtid uintptr) bool
 }
 
 // Raw represents raw formatted bytes.
-// We "blindly" store it during encode and retrieve the raw bytes during decode.
-// Note: it is dangerous during encode, so we may gate the behaviour
-// behind an Encode flag which must be explicitly set.
+// We "blindly" store it during encode and store the raw bytes during decode.
+// Note: it is dangerous during encode, so we may gate the behaviour behind an Encode flag which must be explicitly set.
 type Raw []byte
 
 // RawExt represents raw unprocessed extension data.
-// Some codecs will decode extension data as a *RawExt
-// if there is no registered extension for the tag.
+// Some codecs will decode extension data as a *RawExt if there is no registered extension for the tag.
 //
-// Only one of Data or Value is nil.
-// If Data is nil, then the content of the RawExt is in the Value.
+// Only one of Data or Value is nil. If Data is nil, then the content of the RawExt is in the Value.
 type RawExt struct {
 	Tag uint64
-	// Data is the []byte which represents the raw ext. If nil, ext is exposed in Value.
-	// Data is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of types
+	// Data is the []byte which represents the raw ext. If Data is nil, ext is exposed in Value.
+	// Data is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types
 	Data []byte
 	// Value represents the extension, if Data is nil.
-	// Value is used by codecs (e.g. cbor, json) which leverage the format to do
-	// custom serialization of the types.
+	// Value is used by codecs (e.g. cbor, json) which use the format to do custom serialization of the types.
 	Value interface{}
 }
 
@@ -509,30 +385,24 @@ type RawExt struct {
 type BytesExt interface {
 	// WriteExt converts a value to a []byte.
 	//
-	// Note: v is a pointer iff the registered extension type is a struct or array kind.
+	// Note: v *may* be a pointer to the extension type, if the extension type was a struct or array.
 	WriteExt(v interface{}) []byte
 
 	// ReadExt updates a value from a []byte.
-	//
-	// Note: dst is always a pointer kind to the registered extension type.
 	ReadExt(dst interface{}, src []byte)
 }
 
 // InterfaceExt handles custom (de)serialization of types to/from another interface{} value.
 // The Encoder or Decoder will then handle the further (de)serialization of that known type.
 //
-// It is used by codecs (e.g. cbor, json) which use the format to do custom serialization of types.
+// It is used by codecs (e.g. cbor, json) which use the format to do custom serialization of the types.
 type InterfaceExt interface {
-	// ConvertExt converts a value into a simpler interface for easy encoding
-	// e.g. convert time.Time to int64.
+	// ConvertExt converts a value into a simpler interface for easy encoding e.g. convert time.Time to int64.
 	//
-	// Note: v is a pointer iff the registered extension type is a struct or array kind.
+	// Note: v *may* be a pointer to the extension type, if the extension type was a struct or array.
 	ConvertExt(v interface{}) interface{}
 
-	// UpdateExt updates a value from a simpler interface for easy decoding
-	// e.g. convert int64 to time.Time.
-	//
-	// Note: dst is always a pointer kind to the registered extension type.
+	// UpdateExt updates a value from a simpler interface for easy decoding e.g. convert int64 to time.Time.
 	UpdateExt(dst interface{}, src interface{})
 }
 
@@ -570,59 +440,64 @@ func (x addExtWrapper) UpdateExt(dest interface{}, v interface{}) {
 	x.ReadExt(dest, v.([]byte))
 }
 
-type extWrapper struct {
-	BytesExt
-	InterfaceExt
+type setExtWrapper struct {
+	b BytesExt
+	i InterfaceExt
 }
 
-type bytesExtFailer struct{}
-
-func (bytesExtFailer) WriteExt(v interface{}) []byte {
-	panicv.errorstr("BytesExt.WriteExt is not supported")
-	return nil
+func (x *setExtWrapper) WriteExt(v interface{}) []byte {
+	if x.b == nil {
+		panic("BytesExt.WriteExt is not supported")
+	}
+	return x.b.WriteExt(v)
 }
-func (bytesExtFailer) ReadExt(v interface{}, bs []byte) {
-	panicv.errorstr("BytesExt.ReadExt is not supported")
+
+func (x *setExtWrapper) ReadExt(v interface{}, bs []byte) {
+	if x.b == nil {
+		panic("BytesExt.WriteExt is not supported")
+
+	}
+	x.b.ReadExt(v, bs)
 }
 
-type interfaceExtFailer struct{}
+func (x *setExtWrapper) ConvertExt(v interface{}) interface{} {
+	if x.i == nil {
+		panic("InterfaceExt.ConvertExt is not supported")
 
-func (interfaceExtFailer) ConvertExt(v interface{}) interface{} {
-	panicv.errorstr("InterfaceExt.ConvertExt is not supported")
-	return nil
+	}
+	return x.i.ConvertExt(v)
 }
-func (interfaceExtFailer) UpdateExt(dest interface{}, v interface{}) {
-	panicv.errorstr("InterfaceExt.UpdateExt is not supported")
+
+func (x *setExtWrapper) UpdateExt(dest interface{}, v interface{}) {
+	if x.i == nil {
+		panic("InterfaceExxt.UpdateExt is not supported")
+
+	}
+	x.i.UpdateExt(dest, v)
 }
 
+// type errorString string
+// func (x errorString) Error() string { return string(x) }
+
 type binaryEncodingType struct{}
 
-func (binaryEncodingType) isBinary() bool { return true }
+func (_ binaryEncodingType) isBinary() bool { return true }
 
 type textEncodingType struct{}
 
-func (textEncodingType) isBinary() bool { return false }
+func (_ textEncodingType) isBinary() bool { return false }
 
 // noBuiltInTypes is embedded into many types which do not support builtins
 // e.g. msgpack, simple, cbor.
-
-// type noBuiltInTypeChecker struct{}
-// func (noBuiltInTypeChecker) IsBuiltinType(rt uintptr) bool { return false }
-// type noBuiltInTypes struct{ noBuiltInTypeChecker }
-
 type noBuiltInTypes struct{}
 
-func (noBuiltInTypes) EncodeBuiltin(rt uintptr, v interface{}) {}
-func (noBuiltInTypes) DecodeBuiltin(rt uintptr, v interface{}) {}
+func (_ noBuiltInTypes) IsBuiltinType(rt uintptr) bool           { return false }
+func (_ noBuiltInTypes) EncodeBuiltin(rt uintptr, v interface{}) {}
+func (_ noBuiltInTypes) DecodeBuiltin(rt uintptr, v interface{}) {}
 
-// type noStreamingCodec struct{}
-// func (noStreamingCodec) CheckBreak() bool { return false }
-// func (noStreamingCodec) hasElemSeparators() bool { return false }
+type noStreamingCodec struct{}
 
-type noElemSeparators struct{}
-
-func (noElemSeparators) hasElemSeparators() (v bool)            { return }
-func (noElemSeparators) recreateEncDriver(e encDriver) (v bool) { return }
+func (_ noStreamingCodec) CheckBreak() bool { return false }
 
 // bigenHelper.
 // Users must already slice the x completely, because we will not reslice.
@@ -647,256 +522,165 @@ func (z bigenHelper) writeUint64(v uint64) {
 }
 
 type extTypeTagFn struct {
-	rtid    uintptr
-	rtidptr uintptr
-	rt      reflect.Type
-	tag     uint64
-	ext     Ext
-	_       [1]uint64 // padding
+	rtid uintptr
+	rt   reflect.Type
+	tag  uint64
+	ext  Ext
 }
 
 type extHandle []extTypeTagFn
 
+// DEPRECATED: Use SetBytesExt or SetInterfaceExt on the Handle instead.
+//
 // AddExt registes an encode and decode function for a reflect.Type.
+// AddExt internally calls SetExt.
 // To deregister an Ext, call AddExt with nil encfn and/or nil decfn.
-//
-// Deprecated: Use SetBytesExt or SetInterfaceExt on the Handle instead.
-func (o *extHandle) AddExt(rt reflect.Type, tag byte,
-	encfn func(reflect.Value) ([]byte, error),
-	decfn func(reflect.Value, []byte) error) (err error) {
+func (o *extHandle) AddExt(
+	rt reflect.Type, tag byte,
+	encfn func(reflect.Value) ([]byte, error), decfn func(reflect.Value, []byte) error,
+) (err error) {
 	if encfn == nil || decfn == nil {
 		return o.SetExt(rt, uint64(tag), nil)
 	}
 	return o.SetExt(rt, uint64(tag), addExtWrapper{encfn, decfn})
 }
 
-// SetExt will set the extension for a tag and reflect.Type.
-// Note that the type must be a named type, and specifically not a pointer or Interface.
-// An error is returned if that is not honored.
-// To Deregister an ext, call SetExt with nil Ext.
+// DEPRECATED: Use SetBytesExt or SetInterfaceExt on the Handle instead.
 //
-// Deprecated: Use SetBytesExt or SetInterfaceExt on the Handle instead.
+// Note that the type must be a named type, and specifically not
+// a pointer or Interface. An error is returned if that is not honored.
+//
+// To Deregister an ext, call SetExt with nil Ext
 func (o *extHandle) SetExt(rt reflect.Type, tag uint64, ext Ext) (err error) {
 	// o is a pointer, because we may need to initialize it
-	rk := rt.Kind()
-	for rk == reflect.Ptr {
-		rt = rt.Elem()
-		rk = rt.Kind()
-	}
-
-	if rt.PkgPath() == "" || rk == reflect.Interface { // || rk == reflect.Ptr {
-		return fmt.Errorf("codec.Handle.SetExt: Takes named type, not a pointer or interface: %v", rt)
+	if rt.PkgPath() == "" || rt.Kind() == reflect.Interface {
+		err = fmt.Errorf("codec.Handle.AddExt: Takes named type, not a pointer or interface: %T",
+			reflect.Zero(rt).Interface())
+		return
 	}
 
-	rtid := rt2id(rt)
-	switch rtid {
-	case timeTypId, rawTypId, rawExtTypId:
-		// all natively supported type, so cannot have an extension
-		return // TODO: should we silently ignore, or return an error???
-	}
-	// if o == nil {
-	// 	return errors.New("codec.Handle.SetExt: extHandle not initialized")
-	// }
-	o2 := *o
-	// if o2 == nil {
-	// 	return errors.New("codec.Handle.SetExt: extHandle not initialized")
-	// }
-	for i := range o2 {
-		v := &o2[i]
+	rtid := reflect.ValueOf(rt).Pointer()
+	for _, v := range *o {
 		if v.rtid == rtid {
 			v.tag, v.ext = tag, ext
 			return
 		}
 	}
-	rtidptr := rt2id(reflect.PtrTo(rt))
-	*o = append(o2, extTypeTagFn{rtid, rtidptr, rt, tag, ext, [1]uint64{}})
+
+	if *o == nil {
+		*o = make([]extTypeTagFn, 0, 4)
+	}
+	*o = append(*o, extTypeTagFn{rtid, rt, tag, ext})
 	return
 }
 
-func (o extHandle) getExt(rtid uintptr) (v *extTypeTagFn) {
+func (o extHandle) getExt(rtid uintptr) *extTypeTagFn {
+	var v *extTypeTagFn
 	for i := range o {
 		v = &o[i]
-		if v.rtid == rtid || v.rtidptr == rtid {
-			return
+		if v.rtid == rtid {
+			return v
 		}
 	}
 	return nil
 }
 
-func (o extHandle) getExtForTag(tag uint64) (v *extTypeTagFn) {
+func (o extHandle) getExtForTag(tag uint64) *extTypeTagFn {
+	var v *extTypeTagFn
 	for i := range o {
 		v = &o[i]
 		if v.tag == tag {
-			return
+			return v
 		}
 	}
 	return nil
 }
 
-type intf2impl struct {
-	rtid uintptr // for intf
-	impl reflect.Type
-	// _    [1]uint64 // padding // not-needed, as *intf2impl is never returned.
-}
-
-type intf2impls []intf2impl
-
-// Intf2Impl maps an interface to an implementing type.
-// This allows us support infering the concrete type
-// and populating it when passed an interface.
-// e.g. var v io.Reader can be decoded as a bytes.Buffer, etc.
-//
-// Passing a nil impl will clear the mapping.
-func (o *intf2impls) Intf2Impl(intf, impl reflect.Type) (err error) {
-	if impl != nil && !impl.Implements(intf) {
-		return fmt.Errorf("Intf2Impl: %v does not implement %v", impl, intf)
-	}
-	rtid := rt2id(intf)
-	o2 := *o
-	for i := range o2 {
-		v := &o2[i]
-		if v.rtid == rtid {
-			v.impl = impl
-			return
-		}
-	}
-	*o = append(o2, intf2impl{rtid, impl})
-	return
-}
-
-func (o intf2impls) intf2impl(rtid uintptr) (rv reflect.Value) {
-	for i := range o {
-		v := &o[i]
-		if v.rtid == rtid {
-			if v.impl == nil {
-				return
-			}
-			if v.impl.Kind() == reflect.Ptr {
-				return reflect.New(v.impl.Elem())
-			}
-			return reflect.New(v.impl).Elem()
-		}
-	}
-	return
-}
-
-type structFieldInfoFlag uint8
-
-const (
-	_ structFieldInfoFlag = 1 << iota
-	structFieldInfoFlagReady
-	structFieldInfoFlagOmitEmpty
-)
-
-func (x *structFieldInfoFlag) flagSet(f structFieldInfoFlag) {
-	*x = *x | f
-}
-
-func (x *structFieldInfoFlag) flagClr(f structFieldInfoFlag) {
-	*x = *x &^ f
-}
-
-func (x structFieldInfoFlag) flagGet(f structFieldInfoFlag) bool {
-	return x&f != 0
-}
-
-func (x structFieldInfoFlag) omitEmpty() bool {
-	return x.flagGet(structFieldInfoFlagOmitEmpty)
-}
-
-func (x structFieldInfoFlag) ready() bool {
-	return x.flagGet(structFieldInfoFlagReady)
-}
-
 type structFieldInfo struct {
 	encName   string // encode name
 	fieldName string // field name
 
-	is  [maxLevelsEmbedding]uint16 // (recursive/embedded) field index in struct
-	nis uint8                      // num levels of embedding. if 1, then it's not embedded.
-	structFieldInfoFlag
-}
+	// only one of 'i' or 'is' can be set. If 'i' is -1, then 'is' has been set.
 
-func (si *structFieldInfo) setToZeroValue(v reflect.Value) {
-	if v, valid := si.field(v, false); valid {
-		v.Set(reflect.Zero(v.Type()))
-	}
+	is        []int // (recursive/embedded) field index in struct
+	i         int16 // field index in struct
+	omitEmpty bool
+	toArray   bool // if field is _struct, is the toArray set?
 }
 
+// func (si *structFieldInfo) isZero() bool {
+// 	return si.encName == "" && len(si.is) == 0 && si.i == 0 && !si.omitEmpty && !si.toArray
+// }
+
 // rv returns the field of the struct.
 // If anonymous, it returns an Invalid
-func (si *structFieldInfo) field(v reflect.Value, update bool) (rv2 reflect.Value, valid bool) {
+func (si *structFieldInfo) field(v reflect.Value, update bool) (rv2 reflect.Value) {
+	if si.i != -1 {
+		v = v.Field(int(si.i))
+		return v
+	}
 	// replicate FieldByIndex
-	for i, x := range si.is {
-		if uint8(i) == si.nis {
-			break
-		}
-		if v, valid = baseStructRv(v, update); !valid {
-			return
+	for _, x := range si.is {
+		for v.Kind() == reflect.Ptr {
+			if v.IsNil() {
+				if !update {
+					return
+				}
+				v.Set(reflect.New(v.Type().Elem()))
+			}
+			v = v.Elem()
 		}
-		v = v.Field(int(x))
+		v = v.Field(x)
 	}
-
-	return v, true
+	return v
 }
 
-// func (si *structFieldInfo) fieldval(v reflect.Value, update bool) reflect.Value {
-// 	v, _ = si.field(v, update)
-// 	return v
-// }
-
-func parseStructInfo(stag string) (toArray, omitEmpty bool, keytype valueType) {
-	keytype = valueTypeString // default
-	if stag == "" {
-		return
-	}
-	for i, s := range strings.Split(stag, ",") {
-		if i == 0 {
-		} else {
-			switch s {
-			case "omitempty":
-				omitEmpty = true
-			case "toarray":
-				toArray = true
-			case "int":
-				keytype = valueTypeInt
-			case "uint":
-				keytype = valueTypeUint
-			case "float":
-				keytype = valueTypeFloat
-				// case "bool":
-				// 	keytype = valueTypeBool
-			case "string":
-				keytype = valueTypeString
+func (si *structFieldInfo) setToZeroValue(v reflect.Value) {
+	if si.i != -1 {
+		v = v.Field(int(si.i))
+		v.Set(reflect.Zero(v.Type()))
+		// v.Set(reflect.New(v.Type()).Elem())
+		// v.Set(reflect.New(v.Type()))
+	} else {
+		// replicate FieldByIndex
+		for _, x := range si.is {
+			for v.Kind() == reflect.Ptr {
+				if v.IsNil() {
+					return
+				}
+				v = v.Elem()
 			}
+			v = v.Field(x)
 		}
+		v.Set(reflect.Zero(v.Type()))
 	}
-	return
 }
 
-func (si *structFieldInfo) parseTag(stag string) {
+func parseStructFieldInfo(fname string, stag string) *structFieldInfo {
 	// if fname == "" {
-	// 	panic(errNoFieldNameToStructFieldInfo)
+	// 	panic(noFieldNameToStructFieldInfoErr)
 	// }
-
-	if stag == "" {
-		return
+	si := structFieldInfo{
+		encName: fname,
 	}
-	for i, s := range strings.Split(stag, ",") {
-		if i == 0 {
-			if s != "" {
-				si.encName = s
-			}
-		} else {
-			switch s {
-			case "omitempty":
-				si.flagSet(structFieldInfoFlagOmitEmpty)
-				// si.omitEmpty = true
-				// case "toarray":
-				// 	si.toArray = true
+
+	if stag != "" {
+		for i, s := range strings.Split(stag, ",") {
+			if i == 0 {
+				if s != "" {
+					si.encName = s
+				}
+			} else {
+				if s == "omitempty" {
+					si.omitEmpty = true
+				} else if s == "toarray" {
+					si.toArray = true
+				}
 			}
 		}
 	}
+	// si.encNameBs = []byte(si.encName)
+	return &si
 }
 
 type sfiSortedByEncName []*structFieldInfo
@@ -913,105 +697,7 @@ func (p sfiSortedByEncName) Swap(i, j int) {
 	p[i], p[j] = p[j], p[i]
 }
 
-const structFieldNodeNumToCache = 4
-
-type structFieldNodeCache struct {
-	rv  [structFieldNodeNumToCache]reflect.Value
-	idx [structFieldNodeNumToCache]uint32
-	num uint8
-}
-
-func (x *structFieldNodeCache) get(key uint32) (fv reflect.Value, valid bool) {
-	for i, k := range &x.idx {
-		if uint8(i) == x.num {
-			return // break
-		}
-		if key == k {
-			return x.rv[i], true
-		}
-	}
-	return
-}
-
-func (x *structFieldNodeCache) tryAdd(fv reflect.Value, key uint32) {
-	if x.num < structFieldNodeNumToCache {
-		x.rv[x.num] = fv
-		x.idx[x.num] = key
-		x.num++
-		return
-	}
-}
-
-type structFieldNode struct {
-	v      reflect.Value
-	cache2 structFieldNodeCache
-	cache3 structFieldNodeCache
-	update bool
-}
-
-func (x *structFieldNode) field(si *structFieldInfo) (fv reflect.Value) {
-	// return si.fieldval(x.v, x.update)
-	// Note: we only cache if nis=2 or nis=3 i.e. up to 2 levels of embedding
-	// This mostly saves us time on the repeated calls to v.Elem, v.Field, etc.
-	var valid bool
-	switch si.nis {
-	case 1:
-		fv = x.v.Field(int(si.is[0]))
-	case 2:
-		if fv, valid = x.cache2.get(uint32(si.is[0])); valid {
-			fv = fv.Field(int(si.is[1]))
-			return
-		}
-		fv = x.v.Field(int(si.is[0]))
-		if fv, valid = baseStructRv(fv, x.update); !valid {
-			return
-		}
-		x.cache2.tryAdd(fv, uint32(si.is[0]))
-		fv = fv.Field(int(si.is[1]))
-	case 3:
-		var key uint32 = uint32(si.is[0])<<16 | uint32(si.is[1])
-		if fv, valid = x.cache3.get(key); valid {
-			fv = fv.Field(int(si.is[2]))
-			return
-		}
-		fv = x.v.Field(int(si.is[0]))
-		if fv, valid = baseStructRv(fv, x.update); !valid {
-			return
-		}
-		fv = fv.Field(int(si.is[1]))
-		if fv, valid = baseStructRv(fv, x.update); !valid {
-			return
-		}
-		x.cache3.tryAdd(fv, key)
-		fv = fv.Field(int(si.is[2]))
-	default:
-		fv, _ = si.field(x.v, x.update)
-	}
-	return
-}
-
-func baseStructRv(v reflect.Value, update bool) (v2 reflect.Value, valid bool) {
-	for v.Kind() == reflect.Ptr {
-		if v.IsNil() {
-			if !update {
-				return
-			}
-			v.Set(reflect.New(v.Type().Elem()))
-		}
-		v = v.Elem()
-	}
-	return v, true
-}
-
-type typeInfoFlag uint8
-
-const (
-	typeInfoFlagComparable = 1 << iota
-	typeInfoFlagIsZeroer
-	typeInfoFlagIsZeroerPtr
-)
-
-// typeInfo keeps information about each (non-ptr) type referenced in the encode/decode sequence.
+// typeInfo keeps information about each type referenced in the encode/decode sequence.
 //
 // During an encode/decode sequence, we work as below:
 //   - If base is a built in type, en/decode base value
@@ -1020,82 +706,70 @@ const (
 //   - If type is text(M/Unm)arshaler, call Text(M/Unm)arshal method
 //   - Else decode appropriately based on the reflect.Kind
 type typeInfo struct {
-	rt      reflect.Type
-	elem    reflect.Type
-	pkgpath string
+	sfi  []*structFieldInfo // sorted. Used when enc/dec struct to map.
+	sfip []*structFieldInfo // unsorted. Used when enc/dec struct to array.
 
+	rt   reflect.Type
 	rtid uintptr
-	// rv0  reflect.Value // saved zero value, used if immutableKind
 
 	numMeth uint16 // number of methods
-	kind    uint8
-	chandir uint8
 
-	anyOmitEmpty bool      // true if a struct, and any of the fields are tagged "omitempty"
-	toArray      bool      // whether this (struct) type should be encoded as an array
-	keyType      valueType // if struct, how is the field name stored in a stream? default is string
-	mbs          bool      // base type (T or *T) is a MapBySlice
+	// baseId gives pointer to the base reflect.Type, after deferencing
+	// the pointers. E.g. base type of ***time.Time is time.Time.
+	base      reflect.Type
+	baseId    uintptr
+	baseIndir int8 // number of indirections to get to base
 
-	// ---- cpu cache line boundary?
-	sfiSort []*structFieldInfo // sorted. Used when enc/dec struct to map.
-	sfiSrc  []*structFieldInfo // unsorted. Used when enc/dec struct to array.
+	mbs bool // base type (T or *T) is a MapBySlice
 
-	key reflect.Type
+	bm        bool // base type (T or *T) is a binaryMarshaler
+	bunm      bool // base type (T or *T) is a binaryUnmarshaler
+	bmIndir   int8 // number of indirections to get to binaryMarshaler type
+	bunmIndir int8 // number of indirections to get to binaryUnmarshaler type
 
-	// ---- cpu cache line boundary?
-	// sfis         []structFieldInfo // all sfi, in src order, as created.
-	sfiNamesSort []byte // all names, with indexes into the sfiSort
+	tm        bool // base type (T or *T) is a textMarshaler
+	tunm      bool // base type (T or *T) is a textUnmarshaler
+	tmIndir   int8 // number of indirections to get to textMarshaler type
+	tunmIndir int8 // number of indirections to get to textUnmarshaler type
 
-	// format of marshal type fields below: [btj][mu]p? OR csp?
+	jm        bool // base type (T or *T) is a jsonMarshaler
+	junm      bool // base type (T or *T) is a jsonUnmarshaler
+	jmIndir   int8 // number of indirections to get to jsonMarshaler type
+	junmIndir int8 // number of indirections to get to jsonUnmarshaler type
 
-	bm  bool // T is a binaryMarshaler
-	bmp bool // *T is a binaryMarshaler
-	bu  bool // T is a binaryUnmarshaler
-	bup bool // *T is a binaryUnmarshaler
-	tm  bool // T is a textMarshaler
-	tmp bool // *T is a textMarshaler
-	tu  bool // T is a textUnmarshaler
-	tup bool // *T is a textUnmarshaler
+	cs      bool // base type (T or *T) is a Selfer
+	csIndir int8 // number of indirections to get to Selfer type
 
-	jm  bool // T is a jsonMarshaler
-	jmp bool // *T is a jsonMarshaler
-	ju  bool // T is a jsonUnmarshaler
-	jup bool // *T is a jsonUnmarshaler
-	cs  bool // T is a Selfer
-	csp bool // *T is a Selfer
-
-	// other flags, with individual bits representing if set.
-	flags typeInfoFlag
-
-	// _ [2]byte   // padding
-	_ [3]uint64 // padding
-}
-
-func (ti *typeInfo) isFlag(f typeInfoFlag) bool {
-	return ti.flags&f != 0
+	toArray bool // whether this (struct) type should be encoded as an array
 }
 
-func (ti *typeInfo) indexForEncName(name []byte) (index int16) {
-	var sn []byte
-	if len(name)+2 <= 32 {
-		var buf [32]byte // should not escape
-		sn = buf[:len(name)+2]
+func (ti *typeInfo) indexForEncName(name string) int {
+	// NOTE: name may be a stringView, so don't pass it to another function.
+	//tisfi := ti.sfi
+	const binarySearchThreshold = 16
+	if sfilen := len(ti.sfi); sfilen < binarySearchThreshold {
+		// linear search. faster than binary search in my testing up to 16-field structs.
+		for i, si := range ti.sfi {
+			if si.encName == name {
+				return i
+			}
+		}
 	} else {
-		sn = make([]byte, len(name)+2)
-	}
-	copy(sn[1:], name)
-	sn[0], sn[len(sn)-1] = tiSep2(name), 0xff
-	j := bytes.Index(ti.sfiNamesSort, sn)
-	if j < 0 {
-		return -1
+		// binary search. adapted from sort/search.go.
+		h, i, j := 0, 0, sfilen
+		for i < j {
+			h = i + (j-i)/2
+			if ti.sfi[h].encName < name {
+				i = h + 1
+			} else {
+				j = h
+			}
+		}
+		if i < sfilen && ti.sfi[i].encName == name {
+			return i
+		}
 	}
-	index = int16(uint16(ti.sfiNamesSort[j+len(sn)+1]) | uint16(ti.sfiNamesSort[j+len(sn)])<<8)
-	return
-}
-
-type rtid2ti struct {
-	rtid uintptr
-	ti   *typeInfo
+	return -1
 }
 
 // TypeInfos caches typeInfo for each type on first inspection.
@@ -1103,11 +777,9 @@ type rtid2ti struct {
 // It is configured with a set of tag keys, which are used to get
 // configuration for the type.
 type TypeInfos struct {
-	// infos: formerly map[uintptr]*typeInfo, now *[]rtid2ti, 2 words expected
-	infos atomicTypeInfoSlice
-	mu    sync.Mutex
+	infos map[uintptr]*typeInfo
+	mu    sync.RWMutex
 	tags  []string
-	_     [2]uint64 // padding
 }
 
 // NewTypeInfos creates a TypeInfos given a set of struct tags keys.
@@ -1115,7 +787,7 @@ type TypeInfos struct {
 // This allows users customize the struct tag keys which contain configuration
 // of their types.
 func NewTypeInfos(tags []string) *TypeInfos {
-	return &TypeInfos{tags: tags}
+	return &TypeInfos{tags: tags, infos: make(map[uintptr]*typeInfo, 64)}
 }
 
 func (x *TypeInfos) structTag(t reflect.StructTag) (s string) {
@@ -1130,124 +802,91 @@ func (x *TypeInfos) structTag(t reflect.StructTag) (s string) {
 	return
 }
 
-func (x *TypeInfos) find(s []rtid2ti, rtid uintptr) (idx int, ti *typeInfo) {
-	// binary search. adapted from sort/search.go.
-	// if sp == nil {
-	// 	return -1, nil
-	// }
-	// s := *sp
-	h, i, j := 0, 0, len(s)
-	for i < j {
-		h = i + (j-i)/2
-		if s[h].rtid < rtid {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	if i < len(s) && s[i].rtid == rtid {
-		return i, s[i].ti
-	}
-	return i, nil
-}
-
 func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
-	sp := x.infos.load()
-	var idx int
-	if sp != nil {
-		idx, pti = x.find(sp, rtid)
-		if pti != nil {
-			return
-		}
-	}
-
-	rk := rt.Kind()
-
-	if rk == reflect.Ptr { // || (rk == reflect.Interface && rtid != intfTypId) {
-		panicv.errorf("invalid kind passed to TypeInfos.get: %v - %v", rk, rt)
+	var ok bool
+	x.mu.RLock()
+	pti, ok = x.infos[rtid]
+	x.mu.RUnlock()
+	if ok {
+		return
 	}
 
 	// do not hold lock while computing this.
 	// it may lead to duplication, but that's ok.
-	ti := typeInfo{rt: rt, rtid: rtid, kind: uint8(rk), pkgpath: rt.PkgPath()}
-	// ti.rv0 = reflect.Zero(rt)
-
-	// ti.comparable = rt.Comparable()
+	ti := typeInfo{rt: rt, rtid: rtid}
 	ti.numMeth = uint16(rt.NumMethod())
 
-	ti.bm, ti.bmp = implIntf(rt, binaryMarshalerTyp)
-	ti.bu, ti.bup = implIntf(rt, binaryUnmarshalerTyp)
-	ti.tm, ti.tmp = implIntf(rt, textMarshalerTyp)
-	ti.tu, ti.tup = implIntf(rt, textUnmarshalerTyp)
-	ti.jm, ti.jmp = implIntf(rt, jsonMarshalerTyp)
-	ti.ju, ti.jup = implIntf(rt, jsonUnmarshalerTyp)
-	ti.cs, ti.csp = implIntf(rt, selferTyp)
-
-	b1, b2 := implIntf(rt, iszeroTyp)
-	if b1 {
-		ti.flags |= typeInfoFlagIsZeroer
+	var indir int8
+	if ok, indir = implementsIntf(rt, binaryMarshalerTyp); ok {
+		ti.bm, ti.bmIndir = true, indir
+	}
+	if ok, indir = implementsIntf(rt, binaryUnmarshalerTyp); ok {
+		ti.bunm, ti.bunmIndir = true, indir
+	}
+	if ok, indir = implementsIntf(rt, textMarshalerTyp); ok {
+		ti.tm, ti.tmIndir = true, indir
+	}
+	if ok, indir = implementsIntf(rt, textUnmarshalerTyp); ok {
+		ti.tunm, ti.tunmIndir = true, indir
+	}
+	if ok, indir = implementsIntf(rt, jsonMarshalerTyp); ok {
+		ti.jm, ti.jmIndir = true, indir
+	}
+	if ok, indir = implementsIntf(rt, jsonUnmarshalerTyp); ok {
+		ti.junm, ti.junmIndir = true, indir
+	}
+	if ok, indir = implementsIntf(rt, selferTyp); ok {
+		ti.cs, ti.csIndir = true, indir
 	}
-	if b2 {
-		ti.flags |= typeInfoFlagIsZeroerPtr
+	if ok, _ = implementsIntf(rt, mapBySliceTyp); ok {
+		ti.mbs = true
 	}
-	if rt.Comparable() {
-		ti.flags |= typeInfoFlagComparable
+
+	pt := rt
+	var ptIndir int8
+	// for ; pt.Kind() == reflect.Ptr; pt, ptIndir = pt.Elem(), ptIndir+1 { }
+	for pt.Kind() == reflect.Ptr {
+		pt = pt.Elem()
+		ptIndir++
+	}
+	if ptIndir == 0 {
+		ti.base = rt
+		ti.baseId = rtid
+	} else {
+		ti.base = pt
+		ti.baseId = reflect.ValueOf(pt).Pointer()
+		ti.baseIndir = ptIndir
 	}
 
-	switch rk {
-	case reflect.Struct:
+	if rt.Kind() == reflect.Struct {
 		var omitEmpty bool
 		if f, ok := rt.FieldByName(structInfoFieldName); ok {
-			ti.toArray, omitEmpty, ti.keyType = parseStructInfo(x.structTag(f.Tag))
-		} else {
-			ti.keyType = valueTypeString
+			siInfo := parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag))
+			ti.toArray = siInfo.toArray
+			omitEmpty = siInfo.omitEmpty
 		}
-		pp, pi := pool.tiLoad()
-		pv := pi.(*typeInfoLoadArray)
-		pv.etypes[0] = ti.rtid
-		// vv := typeInfoLoad{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]}
-		vv := typeInfoLoad{pv.etypes[:1], pv.sfis[:0]}
+		pi := rgetPool.Get()
+		pv := pi.(*rgetPoolT)
+		pv.etypes[0] = ti.baseId
+		vv := rgetT{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]}
 		x.rget(rt, rtid, omitEmpty, nil, &vv)
-		// ti.sfis = vv.sfis
-		ti.sfiSrc, ti.sfiSort, ti.sfiNamesSort, ti.anyOmitEmpty = rgetResolveSFI(rt, vv.sfis, pv)
-		pp.Put(pi)
-	case reflect.Map:
-		ti.elem = rt.Elem()
-		ti.key = rt.Key()
-	case reflect.Slice:
-		ti.mbs, _ = implIntf(rt, mapBySliceTyp)
-		ti.elem = rt.Elem()
-	case reflect.Chan:
-		ti.elem = rt.Elem()
-		ti.chandir = uint8(rt.ChanDir())
-	case reflect.Array, reflect.Ptr:
-		ti.elem = rt.Elem()
+		ti.sfip, ti.sfi = rgetResolveSFI(vv.sfis, pv.sfiidx[:0])
+		rgetPool.Put(pi)
 	}
-	// sfi = sfiSrc
+	// sfi = sfip
 
 	x.mu.Lock()
-	sp = x.infos.load()
-	if sp == nil {
+	if pti, ok = x.infos[rtid]; !ok {
 		pti = &ti
-		vs := []rtid2ti{{rtid, pti}}
-		x.infos.store(vs)
-	} else {
-		idx, pti = x.find(sp, rtid)
-		if pti == nil {
-			pti = &ti
-			vs := make([]rtid2ti, len(sp)+1)
-			copy(vs, sp[:idx])
-			copy(vs[idx+1:], sp[idx:])
-			vs[idx] = rtid2ti{rtid, pti}
-			x.infos.store(vs)
-		}
+		x.infos[rtid] = pti
 	}
 	x.mu.Unlock()
 	return
 }
 
 func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, omitEmpty bool,
-	indexstack []uint16, pv *typeInfoLoad) {
+	indexstack []int, pv *rgetT,
+) {
 	// Read up fields and store how to access the value.
 	//
 	// It uses go's rules for message selectors,
@@ -1256,15 +895,10 @@ func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, omitEmpty bool,
 	// Note: we consciously use slices, not a map, to simulate a set.
 	//       Typically, types have < 16 fields,
 	//       and iteration using equals is faster than maps there
-	flen := rt.NumField()
-	if flen > (1<<maxLevelsEmbedding - 1) {
-		panicv.errorf("codec: types with > %v fields are not supported - has %v fields",
-			(1<<maxLevelsEmbedding - 1), flen)
-	}
-	// pv.sfis = make([]structFieldInfo, flen)
+
 LOOP:
-	for j, jlen := uint16(0), uint16(flen); j < jlen; j++ {
-		f := rt.Field(int(j))
+	for j, jlen := 0, rt.NumField(); j < jlen; j++ {
+		f := rt.Field(j)
 		fkind := f.Type.Kind()
 		// skip if a func type, or is unexported, or structTag value == "-"
 		switch fkind {
@@ -1272,635 +906,194 @@ LOOP:
 			continue LOOP
 		}
 
-		isUnexported := f.PkgPath != ""
-		if isUnexported && !f.Anonymous {
+		// if r1, _ := utf8.DecodeRuneInString(f.Name);
+		// r1 == utf8.RuneError || !unicode.IsUpper(r1) {
+		if f.PkgPath != "" && !f.Anonymous { // unexported, not embedded
 			continue
 		}
 		stag := x.structTag(f.Tag)
 		if stag == "-" {
 			continue
 		}
-		var si structFieldInfo
-		var parsed bool
+		var si *structFieldInfo
 		// if anonymous and no struct tag (or it's blank),
 		// and a struct (or pointer to struct), inline it.
 		if f.Anonymous && fkind != reflect.Interface {
-			// ^^ redundant but ok: per go spec, an embedded pointer type cannot be to an interface
-			ft := f.Type
-			isPtr := ft.Kind() == reflect.Ptr
-			for ft.Kind() == reflect.Ptr {
-				ft = ft.Elem()
-			}
-			isStruct := ft.Kind() == reflect.Struct
-
-			// Ignore embedded fields of unexported non-struct types.
-			// Also, from go1.10, ignore pointers to unexported struct types
-			// because unmarshal cannot assign a new struct to an unexported field.
-			// See https://golang.org/issue/21357
-			if (isUnexported && !isStruct) || (!allowSetUnexportedEmbeddedPtr && isUnexported && isPtr) {
-				continue
-			}
 			doInline := stag == ""
 			if !doInline {
-				si.parseTag(stag)
-				parsed = true
+				si = parseStructFieldInfo("", stag)
 				doInline = si.encName == ""
 				// doInline = si.isZero()
 			}
-			if doInline && isStruct {
-				// if etypes contains this, don't call rget again (as fields are already seen here)
-				ftid := rt2id(ft)
-				// We cannot recurse forever, but we need to track other field depths.
-				// So - we break if we see a type twice (not the first time).
-				// This should be sufficient to handle an embedded type that refers to its
-				// owning type, which then refers to its embedded type.
-				processIt := true
-				numk := 0
-				for _, k := range pv.etypes {
-					if k == ftid {
-						numk++
-						if numk == rgetMaxRecursion {
-							processIt = false
-							break
+			if doInline {
+				ft := f.Type
+				for ft.Kind() == reflect.Ptr {
+					ft = ft.Elem()
+				}
+				if ft.Kind() == reflect.Struct {
+					// if etypes contains this, don't call rget again (as fields are already seen here)
+					ftid := reflect.ValueOf(ft).Pointer()
+					// We cannot recurse forever, but we need to track other field depths.
+					// So - we break if we see a type twice (not the first time).
+					// This should be sufficient to handle an embedded type that refers to its
+					// owning type, which then refers to its embedded type.
+					processIt := true
+					numk := 0
+					for _, k := range pv.etypes {
+						if k == ftid {
+							numk++
+							if numk == rgetMaxRecursion {
+								processIt = false
+								break
+							}
 						}
 					}
+					if processIt {
+						pv.etypes = append(pv.etypes, ftid)
+						indexstack2 := make([]int, len(indexstack)+1)
+						copy(indexstack2, indexstack)
+						indexstack2[len(indexstack)] = j
+						// indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
+						x.rget(ft, ftid, omitEmpty, indexstack2, pv)
+					}
+					continue
 				}
-				if processIt {
-					pv.etypes = append(pv.etypes, ftid)
-					indexstack2 := make([]uint16, len(indexstack)+1)
-					copy(indexstack2, indexstack)
-					indexstack2[len(indexstack)] = j
-					// indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
-					x.rget(ft, ftid, omitEmpty, indexstack2, pv)
-				}
-				continue
 			}
 		}
 
 		// after the anonymous dance: if an unexported field, skip
-		if isUnexported {
+		if f.PkgPath != "" { // unexported
 			continue
 		}
 
 		if f.Name == "" {
-			panic(errNoFieldNameToStructFieldInfo)
+			panic(noFieldNameToStructFieldInfoErr)
 		}
 
-		// pv.fNames = append(pv.fNames, f.Name)
-		// if si.encName == "" {
+		pv.fNames = append(pv.fNames, f.Name)
 
-		if !parsed {
-			si.encName = f.Name
-			si.parseTag(stag)
-			parsed = true
+		if si == nil {
+			si = parseStructFieldInfo(f.Name, stag)
 		} else if si.encName == "" {
 			si.encName = f.Name
 		}
 		si.fieldName = f.Name
-		si.flagSet(structFieldInfoFlagReady)
 
-		// pv.encNames = append(pv.encNames, si.encName)
+		pv.encNames = append(pv.encNames, si.encName)
 
 		// si.ikind = int(f.Type.Kind())
-		if len(indexstack) > maxLevelsEmbedding-1 {
-			panicv.errorf("codec: only supports up to %v depth of embedding - type has %v depth",
-				maxLevelsEmbedding-1, len(indexstack))
+		if len(indexstack) == 0 {
+			si.i = int16(j)
+		} else {
+			si.i = -1
+			si.is = make([]int, len(indexstack)+1)
+			copy(si.is, indexstack)
+			si.is[len(indexstack)] = j
+			// si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
 		}
-		si.nis = uint8(len(indexstack)) + 1
-		copy(si.is[:], indexstack)
-		si.is[len(indexstack)] = j
 
 		if omitEmpty {
-			si.flagSet(structFieldInfoFlagOmitEmpty)
+			si.omitEmpty = true
 		}
 		pv.sfis = append(pv.sfis, si)
 	}
 }
 
-func tiSep(name string) uint8 {
-	// (xn[0]%64) // (between 192-255 - outside ascii BMP)
-	// return 0xfe - (name[0] & 63)
-	// return 0xfe - (name[0] & 63) - uint8(len(name))
-	// return 0xfe - (name[0] & 63) - uint8(len(name)&63)
-	// return ((0xfe - (name[0] & 63)) & 0xf8) | (uint8(len(name) & 0x07))
-	return 0xfe - (name[0] & 63) - uint8(len(name)&63)
-}
-
-func tiSep2(name []byte) uint8 {
-	return 0xfe - (name[0] & 63) - uint8(len(name)&63)
-}
-
 // resolves the struct field info got from a call to rget.
 // Returns a trimmed, unsorted and sorted []*structFieldInfo.
-func rgetResolveSFI(rt reflect.Type, x []structFieldInfo, pv *typeInfoLoadArray) (
-	y, z []*structFieldInfo, ss []byte, anyOmitEmpty bool) {
-	sa := pv.sfiidx[:0]
-	sn := pv.b[:]
-	n := len(x)
-
-	var xn string
-	var ui uint16
-	var sep byte
-
-	for i := range x {
-		ui = uint16(i)
-		xn = x[i].encName // fieldName or encName? use encName for now.
-		if len(xn)+2 > cap(pv.b) {
-			sn = make([]byte, len(xn)+2)
-		} else {
-			sn = sn[:len(xn)+2]
-		}
-		// use a custom sep, so that misses are less frequent,
-		// since the sep (first char in search) is as unique as first char in field name.
-		sep = tiSep(xn)
-		sn[0], sn[len(sn)-1] = sep, 0xff
-		copy(sn[1:], xn)
-		j := bytes.Index(sa, sn)
-		if j == -1 {
-			sa = append(sa, sep)
-			sa = append(sa, xn...)
-			sa = append(sa, 0xff, byte(ui>>8), byte(ui))
-		} else {
-			index := uint16(sa[j+len(sn)+1]) | uint16(sa[j+len(sn)])<<8
-			// one of them must be reset to nil,
-			// and the index updated appropriately to the other one
-			if x[i].nis == x[index].nis {
-			} else if x[i].nis < x[index].nis {
-				sa[j+len(sn)], sa[j+len(sn)+1] = byte(ui>>8), byte(ui)
-				if x[index].ready() {
-					x[index].flagClr(structFieldInfoFlagReady)
-					n--
-				}
-			} else {
-				if x[i].ready() {
-					x[i].flagClr(structFieldInfoFlagReady)
-					n--
+func rgetResolveSFI(x []*structFieldInfo, pv []sfiIdx) (y, z []*structFieldInfo) {
+	var n int
+	for i, v := range x {
+		xn := v.encName //TODO: fieldName or encName? use encName for now.
+		var found bool
+		for j, k := range pv {
+			if k.name == xn {
+				// one of them must be reset to nil, and the index updated appropriately to the other one
+				if len(v.is) == len(x[k.index].is) {
+				} else if len(v.is) < len(x[k.index].is) {
+					pv[j].index = i
+					if x[k.index] != nil {
+						x[k.index] = nil
+						n++
+					}
+				} else {
+					if x[i] != nil {
+						x[i] = nil
+						n++
+					}
 				}
+				found = true
+				break
 			}
 		}
-
-	}
-	var w []structFieldInfo
-	sharingArray := len(x) <= typeInfoLoadArraySfisLen // sharing array with typeInfoLoadArray
-	if sharingArray {
-		w = make([]structFieldInfo, n)
+		if !found {
+			pv = append(pv, sfiIdx{xn, i})
+		}
 	}
 
-	// remove all the nils (non-ready)
-	y = make([]*structFieldInfo, n)
+	// remove all the nils
+	y = make([]*structFieldInfo, len(x)-n)
 	n = 0
-	var sslen int
-	for i := range x {
-		if !x[i].ready() {
+	for _, v := range x {
+		if v == nil {
 			continue
 		}
-		if !anyOmitEmpty && x[i].omitEmpty() {
-			anyOmitEmpty = true
-		}
-		if sharingArray {
-			w[n] = x[i]
-			y[n] = &w[n]
-		} else {
-			y[n] = &x[i]
-		}
-		sslen = sslen + len(x[i].encName) + 4
+		y[n] = v
 		n++
 	}
-	if n != len(y) {
-		panicv.errorf("failure reading struct %v - expecting %d of %d valid fields, got %d",
-			rt, len(y), len(x), n)
-	}
 
 	z = make([]*structFieldInfo, len(y))
 	copy(z, y)
 	sort.Sort(sfiSortedByEncName(z))
-
-	sharingArray = len(sa) <= typeInfoLoadArraySfiidxLen
-	if sharingArray {
-		ss = make([]byte, 0, sslen)
-	} else {
-		ss = sa[:0] // reuse the newly made sa array if necessary
-	}
-	for i := range z {
-		xn = z[i].encName
-		sep = tiSep(xn)
-		ui = uint16(i)
-		ss = append(ss, sep)
-		ss = append(ss, xn...)
-		ss = append(ss, 0xff, byte(ui>>8), byte(ui))
-	}
 	return
 }
 
-func implIntf(rt, iTyp reflect.Type) (base bool, indir bool) {
-	return rt.Implements(iTyp), reflect.PtrTo(rt).Implements(iTyp)
-}
-
-// isEmptyStruct is only called from isEmptyValue, and checks if a struct is empty:
-//    - does it implement IsZero() bool
-//    - is it comparable, and can i compare directly using ==
-//    - if checkStruct, then walk through the encodable fields
-//      and check if they are empty or not.
-func isEmptyStruct(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
-	// v is a struct kind - no need to check again.
-	// We only check isZero on a struct kind, to reduce the amount of times
-	// that we lookup the rtid and typeInfo for each type as we walk the tree.
-
-	vt := v.Type()
-	rtid := rt2id(vt)
-	if tinfos == nil {
-		tinfos = defTypeInfos
-	}
-	ti := tinfos.get(rtid, vt)
-	if ti.rtid == timeTypId {
-		return rv2i(v).(time.Time).IsZero()
-	}
-	if ti.isFlag(typeInfoFlagIsZeroerPtr) && v.CanAddr() {
-		return rv2i(v.Addr()).(isZeroer).IsZero()
-	}
-	if ti.isFlag(typeInfoFlagIsZeroer) {
-		return rv2i(v).(isZeroer).IsZero()
-	}
-	if ti.isFlag(typeInfoFlagComparable) {
-		return rv2i(v) == rv2i(reflect.Zero(vt))
-	}
-	if !checkStruct {
-		return false
-	}
-	// We only care about what we can encode/decode,
-	// so that is what we use to check omitEmpty.
-	for _, si := range ti.sfiSrc {
-		sfv, valid := si.field(v, false)
-		if valid && !isEmptyValue(sfv, tinfos, deref, checkStruct) {
-			return false
-		}
-	}
-	return true
-}
-
-// func roundFloat(x float64) float64 {
-// 	t := math.Trunc(x)
-// 	if math.Abs(x-t) >= 0.5 {
-// 		return t + math.Copysign(1, x)
-// 	}
-// 	return t
-// }
-
-func panicToErr(h errstrDecorator, err *error) {
-	// Note: This method MUST be called directly from defer i.e. defer panicToErr ...
-	// else it seems the recover is not fully handled
+func panicToErr(err *error) {
 	if recoverPanicToErr {
 		if x := recover(); x != nil {
-			// fmt.Printf("panic'ing with: %v\n", x)
-			// debug.PrintStack()
-			panicValToErr(h, x, err)
+			//debug.PrintStack()
+			panicValToErr(x, err)
 		}
 	}
 }
 
-func panicValToErr(h errstrDecorator, v interface{}, err *error) {
-	switch xerr := v.(type) {
-	case nil:
-	case error:
-		switch xerr {
-		case nil:
-		case io.EOF, io.ErrUnexpectedEOF, errEncoderNotInitialized, errDecoderNotInitialized:
-			// treat as special (bubble up)
-			*err = xerr
-		default:
-			h.wrapErrstr(xerr.Error(), err)
-		}
-	case string:
-		if xerr != "" {
-			h.wrapErrstr(xerr, err)
-		}
-	case fmt.Stringer:
-		if xerr != nil {
-			h.wrapErrstr(xerr.String(), err)
-		}
-	default:
-		h.wrapErrstr(v, err)
-	}
-}
+// func doPanic(tag string, format string, params ...interface{}) {
+// 	params2 := make([]interface{}, len(params)+1)
+// 	params2[0] = tag
+// 	copy(params2[1:], params)
+// 	panic(fmt.Errorf("%s: "+format, params2...))
+// }
 
 func isImmutableKind(k reflect.Kind) (v bool) {
-	return immutableKindsSet[k]
-}
-
-// ----
-
-type codecFnInfo struct {
-	ti    *typeInfo
-	xfFn  Ext
-	xfTag uint64
-	seq   seqType
-	addrD bool
-	addrF bool // if addrD, this says whether decode function can take a value or a ptr
-	addrE bool
-	ready bool // ready to use
-}
-
-// codecFn encapsulates the captured variables and the encode function.
-// This way, we only do some calculations one times, and pass to the
-// code block that should be called (encapsulated in a function)
-// instead of executing the checks every time.
-type codecFn struct {
-	i  codecFnInfo
-	fe func(*Encoder, *codecFnInfo, reflect.Value)
-	fd func(*Decoder, *codecFnInfo, reflect.Value)
-	_  [1]uint64 // padding
-}
-
-type codecRtidFn struct {
-	rtid uintptr
-	fn   *codecFn
-}
-
-type codecFner struct {
-	// hh Handle
-	h  *BasicHandle
-	s  []codecRtidFn
-	be bool
-	js bool
-	_  [6]byte   // padding
-	_  [3]uint64 // padding
-}
-
-func (c *codecFner) reset(hh Handle) {
-	bh := hh.getBasicHandle()
-	// only reset iff extensions changed or *TypeInfos changed
-	var hhSame = true &&
-		c.h == bh && c.h.TypeInfos == bh.TypeInfos &&
-		len(c.h.extHandle) == len(bh.extHandle) &&
-		(len(c.h.extHandle) == 0 || &c.h.extHandle[0] == &bh.extHandle[0])
-	if !hhSame {
-		// c.hh = hh
-		c.h, bh = bh, c.h // swap both
-		_, c.js = hh.(*JsonHandle)
-		c.be = hh.isBinary()
-		for i := range c.s {
-			c.s[i].fn.i.ready = false
-		}
-	}
-}
-
-func (c *codecFner) get(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *codecFn) {
-	rtid := rt2id(rt)
-
-	for _, x := range c.s {
-		if x.rtid == rtid {
-			// if rtid exists, then there's a *codenFn attached (non-nil)
-			fn = x.fn
-			if fn.i.ready {
-				return
-			}
-			break
-		}
-	}
-	var ti *typeInfo
-	if fn == nil {
-		fn = new(codecFn)
-		if c.s == nil {
-			c.s = make([]codecRtidFn, 0, 8)
-		}
-		c.s = append(c.s, codecRtidFn{rtid, fn})
-	} else {
-		ti = fn.i.ti
-		*fn = codecFn{}
-		fn.i.ti = ti
-		// fn.fe, fn.fd = nil, nil
-	}
-	fi := &(fn.i)
-	fi.ready = true
-	if ti == nil {
-		ti = c.h.getTypeInfo(rtid, rt)
-		fi.ti = ti
-	}
-
-	rk := reflect.Kind(ti.kind)
-
-	if checkCodecSelfer && (ti.cs || ti.csp) {
-		fn.fe = (*Encoder).selferMarshal
-		fn.fd = (*Decoder).selferUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.csp
-		fi.addrE = ti.csp
-	} else if rtid == timeTypId {
-		fn.fe = (*Encoder).kTime
-		fn.fd = (*Decoder).kTime
-	} else if rtid == rawTypId {
-		fn.fe = (*Encoder).raw
-		fn.fd = (*Decoder).raw
-	} else if rtid == rawExtTypId {
-		fn.fe = (*Encoder).rawExt
-		fn.fd = (*Decoder).rawExt
-		fi.addrF = true
-		fi.addrD = true
-		fi.addrE = true
-	} else if xfFn := c.h.getExt(rtid); xfFn != nil {
-		fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext
-		fn.fe = (*Encoder).ext
-		fn.fd = (*Decoder).ext
-		fi.addrF = true
-		fi.addrD = true
-		if rk == reflect.Struct || rk == reflect.Array {
-			fi.addrE = true
-		}
-	} else if supportMarshalInterfaces && c.be && (ti.bm || ti.bmp) && (ti.bu || ti.bup) {
-		fn.fe = (*Encoder).binaryMarshal
-		fn.fd = (*Decoder).binaryUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.bup
-		fi.addrE = ti.bmp
-	} else if supportMarshalInterfaces && !c.be && c.js && (ti.jm || ti.jmp) && (ti.ju || ti.jup) {
-		//If JSON, we should check JSONMarshal before textMarshal
-		fn.fe = (*Encoder).jsonMarshal
-		fn.fd = (*Decoder).jsonUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.jup
-		fi.addrE = ti.jmp
-	} else if supportMarshalInterfaces && !c.be && (ti.tm || ti.tmp) && (ti.tu || ti.tup) {
-		fn.fe = (*Encoder).textMarshal
-		fn.fd = (*Decoder).textUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.tup
-		fi.addrE = ti.tmp
-	} else {
-		if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
-			if ti.pkgpath == "" { // un-named slice or map
-				if idx := fastpathAV.index(rtid); idx != -1 {
-					fn.fe = fastpathAV[idx].encfn
-					fn.fd = fastpathAV[idx].decfn
-					fi.addrD = true
-					fi.addrF = false
-				}
-			} else {
-				// use mapping for underlying type if there
-				var rtu reflect.Type
-				if rk == reflect.Map {
-					rtu = reflect.MapOf(ti.key, ti.elem)
-				} else {
-					rtu = reflect.SliceOf(ti.elem)
-				}
-				rtuid := rt2id(rtu)
-				if idx := fastpathAV.index(rtuid); idx != -1 {
-					xfnf := fastpathAV[idx].encfn
-					xrt := fastpathAV[idx].rt
-					fn.fe = func(e *Encoder, xf *codecFnInfo, xrv reflect.Value) {
-						xfnf(e, xf, xrv.Convert(xrt))
-					}
-					fi.addrD = true
-					fi.addrF = false // meaning it can be an address(ptr) or a value
-					xfnf2 := fastpathAV[idx].decfn
-					fn.fd = func(d *Decoder, xf *codecFnInfo, xrv reflect.Value) {
-						if xrv.Kind() == reflect.Ptr {
-							xfnf2(d, xf, xrv.Convert(reflect.PtrTo(xrt)))
-						} else {
-							xfnf2(d, xf, xrv.Convert(xrt))
-						}
-					}
-				}
-			}
-		}
-		if fn.fe == nil && fn.fd == nil {
-			switch rk {
-			case reflect.Bool:
-				fn.fe = (*Encoder).kBool
-				fn.fd = (*Decoder).kBool
-			case reflect.String:
-				fn.fe = (*Encoder).kString
-				fn.fd = (*Decoder).kString
-			case reflect.Int:
-				fn.fd = (*Decoder).kInt
-				fn.fe = (*Encoder).kInt
-			case reflect.Int8:
-				fn.fe = (*Encoder).kInt8
-				fn.fd = (*Decoder).kInt8
-			case reflect.Int16:
-				fn.fe = (*Encoder).kInt16
-				fn.fd = (*Decoder).kInt16
-			case reflect.Int32:
-				fn.fe = (*Encoder).kInt32
-				fn.fd = (*Decoder).kInt32
-			case reflect.Int64:
-				fn.fe = (*Encoder).kInt64
-				fn.fd = (*Decoder).kInt64
-			case reflect.Uint:
-				fn.fd = (*Decoder).kUint
-				fn.fe = (*Encoder).kUint
-			case reflect.Uint8:
-				fn.fe = (*Encoder).kUint8
-				fn.fd = (*Decoder).kUint8
-			case reflect.Uint16:
-				fn.fe = (*Encoder).kUint16
-				fn.fd = (*Decoder).kUint16
-			case reflect.Uint32:
-				fn.fe = (*Encoder).kUint32
-				fn.fd = (*Decoder).kUint32
-			case reflect.Uint64:
-				fn.fe = (*Encoder).kUint64
-				fn.fd = (*Decoder).kUint64
-			case reflect.Uintptr:
-				fn.fe = (*Encoder).kUintptr
-				fn.fd = (*Decoder).kUintptr
-			case reflect.Float32:
-				fn.fe = (*Encoder).kFloat32
-				fn.fd = (*Decoder).kFloat32
-			case reflect.Float64:
-				fn.fe = (*Encoder).kFloat64
-				fn.fd = (*Decoder).kFloat64
-			case reflect.Invalid:
-				fn.fe = (*Encoder).kInvalid
-				fn.fd = (*Decoder).kErr
-			case reflect.Chan:
-				fi.seq = seqTypeChan
-				fn.fe = (*Encoder).kSlice
-				fn.fd = (*Decoder).kSlice
-			case reflect.Slice:
-				fi.seq = seqTypeSlice
-				fn.fe = (*Encoder).kSlice
-				fn.fd = (*Decoder).kSlice
-			case reflect.Array:
-				fi.seq = seqTypeArray
-				fn.fe = (*Encoder).kSlice
-				fi.addrF = false
-				fi.addrD = false
-				rt2 := reflect.SliceOf(ti.elem)
-				fn.fd = func(d *Decoder, xf *codecFnInfo, xrv reflect.Value) {
-					d.cfer().get(rt2, true, false).fd(d, xf, xrv.Slice(0, xrv.Len()))
-				}
-				// fn.fd = (*Decoder).kArray
-			case reflect.Struct:
-				if ti.anyOmitEmpty {
-					fn.fe = (*Encoder).kStruct
-				} else {
-					fn.fe = (*Encoder).kStructNoOmitempty
-				}
-				fn.fd = (*Decoder).kStruct
-			case reflect.Map:
-				fn.fe = (*Encoder).kMap
-				fn.fd = (*Decoder).kMap
-			case reflect.Interface:
-				// encode: reflect.Interface are handled already by preEncodeValue
-				fn.fd = (*Decoder).kInterface
-				fn.fe = (*Encoder).kErr
-			default:
-				// reflect.Ptr and reflect.Interface are handled already by preEncodeValue
-				fn.fe = (*Encoder).kErr
-				fn.fd = (*Decoder).kErr
-			}
-		}
-	}
-	return
-}
-
-type codecFnPooler struct {
-	cf  *codecFner
-	cfp *sync.Pool
-	hh  Handle
-}
-
-func (d *codecFnPooler) cfer() *codecFner {
-	if d.cf == nil {
-		var v interface{}
-		d.cfp, v = pool.codecFner()
-		d.cf = v.(*codecFner)
-		d.cf.reset(d.hh)
-	}
-	return d.cf
-}
-
-func (d *codecFnPooler) alwaysAtEnd() {
-	if d.cf != nil {
-		d.cfp.Put(d.cf)
-		d.cf, d.cfp = nil, nil
-	}
-}
-
-// ----
-
-// these "checkOverflow" functions must be inlinable, and not call anybody.
-// Overflow means that the value cannot be represented without wrapping/overflow.
-// Overflow=false does not mean that the value can be represented without losing precision
-// (especially for floating point).
-
+	return false ||
+		k == reflect.Int ||
+		k == reflect.Int8 ||
+		k == reflect.Int16 ||
+		k == reflect.Int32 ||
+		k == reflect.Int64 ||
+		k == reflect.Uint ||
+		k == reflect.Uint8 ||
+		k == reflect.Uint16 ||
+		k == reflect.Uint32 ||
+		k == reflect.Uint64 ||
+		k == reflect.Uintptr ||
+		k == reflect.Float32 ||
+		k == reflect.Float64 ||
+		k == reflect.Bool ||
+		k == reflect.String
+}
+
+// these functions must be inlinable, and not call anybody
 type checkOverflow struct{}
 
-// func (checkOverflow) Float16(f float64) (overflow bool) {
-// 	panicv.errorf("unimplemented")
-// 	if f < 0 {
-// 		f = -f
-// 	}
-// 	return math.MaxFloat32 < f && f <= math.MaxFloat64
-// }
-
-func (checkOverflow) Float32(v float64) (overflow bool) {
-	if v < 0 {
-		v = -v
+func (_ checkOverflow) Float32(f float64) (overflow bool) {
+	if f < 0 {
+		f = -f
 	}
-	return math.MaxFloat32 < v && v <= math.MaxFloat64
+	return math.MaxFloat32 < f && f <= math.MaxFloat64
 }
-func (checkOverflow) Uint(v uint64, bitsize uint8) (overflow bool) {
+
+func (_ checkOverflow) Uint(v uint64, bitsize uint8) (overflow bool) {
 	if bitsize == 0 || bitsize >= 64 || v == 0 {
 		return
 	}
@@ -1909,7 +1102,8 @@ func (checkOverflow) Uint(v uint64, bitsize uint8) (overflow bool) {
 	}
 	return
 }
-func (checkOverflow) Int(v int64, bitsize uint8) (overflow bool) {
+
+func (_ checkOverflow) Int(v int64, bitsize uint8) (overflow bool) {
 	if bitsize == 0 || bitsize >= 64 || v == 0 {
 		return
 	}
@@ -1918,76 +1112,38 @@ func (checkOverflow) Int(v int64, bitsize uint8) (overflow bool) {
 	}
 	return
 }
-func (checkOverflow) SignedInt(v uint64) (overflow bool) {
+
+func (_ checkOverflow) SignedInt(v uint64) (i int64, overflow bool) {
 	//e.g. -127 to 128 for int8
 	pos := (v >> 63) == 0
 	ui2 := v & 0x7fffffffffffffff
 	if pos {
 		if ui2 > math.MaxInt64 {
 			overflow = true
+			return
 		}
 	} else {
 		if ui2 > math.MaxInt64-1 {
 			overflow = true
+			return
 		}
 	}
+	i = int64(v)
 	return
 }
 
-func (x checkOverflow) Float32V(v float64) float64 {
-	if x.Float32(v) {
-		panicv.errorf("float32 overflow: %v", v)
-	}
-	return v
-}
-func (x checkOverflow) UintV(v uint64, bitsize uint8) uint64 {
-	if x.Uint(v, bitsize) {
-		panicv.errorf("uint64 overflow: %v", v)
-	}
-	return v
-}
-func (x checkOverflow) IntV(v int64, bitsize uint8) int64 {
-	if x.Int(v, bitsize) {
-		panicv.errorf("int64 overflow: %v", v)
-	}
-	return v
-}
-func (x checkOverflow) SignedIntV(v uint64) int64 {
-	if x.SignedInt(v) {
-		panicv.errorf("uint64 to int64 overflow: %v", v)
-	}
-	return int64(v)
-}
-
 // ------------------ SORT -----------------
 
 func isNaN(f float64) bool { return f != f }
 
 // -----------------------
 
-type ioFlusher interface {
-	Flush() error
-}
-
-type ioPeeker interface {
-	Peek(int) ([]byte, error)
-}
-
-type ioBuffered interface {
-	Buffered() int
-}
-
-// -----------------------
-
 type intSlice []int64
 type uintSlice []uint64
-
-// type uintptrSlice []uintptr
 type floatSlice []float64
 type boolSlice []bool
 type stringSlice []string
-
-// type bytesSlice [][]byte
+type bytesSlice [][]byte
 
 func (p intSlice) Len() int           { return len(p) }
 func (p intSlice) Less(i, j int) bool { return p[i] < p[j] }
@@ -1997,10 +1153,6 @@ func (p uintSlice) Len() int           { return len(p) }
 func (p uintSlice) Less(i, j int) bool { return p[i] < p[j] }
 func (p uintSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
 
-// func (p uintptrSlice) Len() int           { return len(p) }
-// func (p uintptrSlice) Less(i, j int) bool { return p[i] < p[j] }
-// func (p uintptrSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
 func (p floatSlice) Len() int { return len(p) }
 func (p floatSlice) Less(i, j int) bool {
 	return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j])
@@ -2011,9 +1163,9 @@ func (p stringSlice) Len() int           { return len(p) }
 func (p stringSlice) Less(i, j int) bool { return p[i] < p[j] }
 func (p stringSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
 
-// func (p bytesSlice) Len() int           { return len(p) }
-// func (p bytesSlice) Less(i, j int) bool { return bytes.Compare(p[i], p[j]) == -1 }
-// func (p bytesSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+func (p bytesSlice) Len() int           { return len(p) }
+func (p bytesSlice) Less(i, j int) bool { return bytes.Compare(p[i], p[j]) == -1 }
+func (p bytesSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
 
 func (p boolSlice) Len() int           { return len(p) }
 func (p boolSlice) Less(i, j int) bool { return !p[i] && p[j] }
@@ -2051,11 +1203,6 @@ type bytesRv struct {
 	r reflect.Value
 }
 type bytesRvSlice []bytesRv
-type timeRv struct {
-	v time.Time
-	r reflect.Value
-}
-type timeRvSlice []timeRv
 
 func (p intRvSlice) Len() int           { return len(p) }
 func (p intRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
@@ -2083,10 +1230,6 @@ func (p boolRvSlice) Len() int           { return len(p) }
 func (p boolRvSlice) Less(i, j int) bool { return !p[i].v && p[j].v }
 func (p boolRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
 
-func (p timeRvSlice) Len() int           { return len(p) }
-func (p timeRvSlice) Less(i, j int) bool { return p[i].v.Before(p[j].v) }
-func (p timeRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
 // -----------------
 
 type bytesI struct {
@@ -2106,6 +1249,7 @@ type set []uintptr
 
 func (s *set) add(v uintptr) (exists bool) {
 	// e.ci is always nil, or len >= 1
+	// defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Add: %v, exists: %v\n", v, exists) }()
 	x := *s
 	if x == nil {
 		x = make([]uintptr, 1, 8)
@@ -2146,6 +1290,7 @@ func (s *set) add(v uintptr) (exists bool) {
 }
 
 func (s *set) remove(v uintptr) (exists bool) {
+	// defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Rm: %v, exists: %v\n", v, exists) }()
 	x := *s
 	if len(x) == 0 {
 		return
@@ -2167,248 +1312,3 @@ func (s *set) remove(v uintptr) (exists bool) {
 	}
 	return
 }
-
-// ------
-
-// bitset types are better than [256]bool, because they permit the whole
-// bitset array being on a single cache line and use less memory.
-
-// given x > 0 and n > 0 and x is exactly 2^n, then pos/x === pos>>n AND pos%x === pos&(x-1).
-// consequently, pos/32 === pos>>5, pos/16 === pos>>4, pos/8 === pos>>3, pos%8 == pos&7
-
-type bitset256 [32]byte
-
-func (x *bitset256) isset(pos byte) bool {
-	return x[pos>>3]&(1<<(pos&7)) != 0
-}
-func (x *bitset256) issetv(pos byte) byte {
-	return x[pos>>3] & (1 << (pos & 7))
-}
-func (x *bitset256) set(pos byte) {
-	x[pos>>3] |= (1 << (pos & 7))
-}
-
-// func (x *bitset256) unset(pos byte) {
-// 	x[pos>>3] &^= (1 << (pos & 7))
-// }
-
-type bitset128 [16]byte
-
-func (x *bitset128) isset(pos byte) bool {
-	return x[pos>>3]&(1<<(pos&7)) != 0
-}
-func (x *bitset128) set(pos byte) {
-	x[pos>>3] |= (1 << (pos & 7))
-}
-
-// func (x *bitset128) unset(pos byte) {
-// 	x[pos>>3] &^= (1 << (pos & 7))
-// }
-
-type bitset32 [4]byte
-
-func (x *bitset32) isset(pos byte) bool {
-	return x[pos>>3]&(1<<(pos&7)) != 0
-}
-func (x *bitset32) set(pos byte) {
-	x[pos>>3] |= (1 << (pos & 7))
-}
-
-// func (x *bitset32) unset(pos byte) {
-// 	x[pos>>3] &^= (1 << (pos & 7))
-// }
-
-// type bit2set256 [64]byte
-
-// func (x *bit2set256) set(pos byte, v1, v2 bool) {
-// 	var pos2 uint8 = (pos & 3) << 1 // returning 0, 2, 4 or 6
-// 	if v1 {
-// 		x[pos>>2] |= 1 << (pos2 + 1)
-// 	}
-// 	if v2 {
-// 		x[pos>>2] |= 1 << pos2
-// 	}
-// }
-// func (x *bit2set256) get(pos byte) uint8 {
-// 	var pos2 uint8 = (pos & 3) << 1     // returning 0, 2, 4 or 6
-// 	return x[pos>>2] << (6 - pos2) >> 6 // 11000000 -> 00000011
-// }
-
-// ------------
-
-type pooler struct {
-	dn                                          sync.Pool // for decNaked
-	cfn                                         sync.Pool // for codecFner
-	tiload                                      sync.Pool
-	strRv8, strRv16, strRv32, strRv64, strRv128 sync.Pool // for stringRV
-}
-
-func (p *pooler) init() {
-	p.strRv8.New = func() interface{} { return new([8]stringRv) }
-	p.strRv16.New = func() interface{} { return new([16]stringRv) }
-	p.strRv32.New = func() interface{} { return new([32]stringRv) }
-	p.strRv64.New = func() interface{} { return new([64]stringRv) }
-	p.strRv128.New = func() interface{} { return new([128]stringRv) }
-	p.dn.New = func() interface{} { x := new(decNaked); x.init(); return x }
-	p.tiload.New = func() interface{} { return new(typeInfoLoadArray) }
-	p.cfn.New = func() interface{} { return new(codecFner) }
-}
-
-func (p *pooler) stringRv8() (sp *sync.Pool, v interface{}) {
-	return &p.strRv8, p.strRv8.Get()
-}
-func (p *pooler) stringRv16() (sp *sync.Pool, v interface{}) {
-	return &p.strRv16, p.strRv16.Get()
-}
-func (p *pooler) stringRv32() (sp *sync.Pool, v interface{}) {
-	return &p.strRv32, p.strRv32.Get()
-}
-func (p *pooler) stringRv64() (sp *sync.Pool, v interface{}) {
-	return &p.strRv64, p.strRv64.Get()
-}
-func (p *pooler) stringRv128() (sp *sync.Pool, v interface{}) {
-	return &p.strRv128, p.strRv128.Get()
-}
-func (p *pooler) decNaked() (sp *sync.Pool, v interface{}) {
-	return &p.dn, p.dn.Get()
-}
-func (p *pooler) codecFner() (sp *sync.Pool, v interface{}) {
-	return &p.cfn, p.cfn.Get()
-}
-func (p *pooler) tiLoad() (sp *sync.Pool, v interface{}) {
-	return &p.tiload, p.tiload.Get()
-}
-
-// func (p *pooler) decNaked() (v *decNaked, f func(*decNaked) ) {
-// 	sp := &(p.dn)
-// 	vv := sp.Get()
-// 	return vv.(*decNaked), func(x *decNaked) { sp.Put(vv) }
-// }
-// func (p *pooler) decNakedGet() (v interface{}) {
-// 	return p.dn.Get()
-// }
-// func (p *pooler) codecFnerGet() (v interface{}) {
-// 	return p.cfn.Get()
-// }
-// func (p *pooler) tiLoadGet() (v interface{}) {
-// 	return p.tiload.Get()
-// }
-// func (p *pooler) decNakedPut(v interface{}) {
-// 	p.dn.Put(v)
-// }
-// func (p *pooler) codecFnerPut(v interface{}) {
-// 	p.cfn.Put(v)
-// }
-// func (p *pooler) tiLoadPut(v interface{}) {
-// 	p.tiload.Put(v)
-// }
-
-type panicHdl struct{}
-
-func (panicHdl) errorv(err error) {
-	if err != nil {
-		panic(err)
-	}
-}
-
-func (panicHdl) errorstr(message string) {
-	if message != "" {
-		panic(message)
-	}
-}
-
-func (panicHdl) errorf(format string, params ...interface{}) {
-	if format != "" {
-		if len(params) == 0 {
-			panic(format)
-		} else {
-			panic(fmt.Sprintf(format, params...))
-		}
-	}
-}
-
-type errstrDecorator interface {
-	wrapErrstr(interface{}, *error)
-}
-
-type errstrDecoratorDef struct{}
-
-func (errstrDecoratorDef) wrapErrstr(v interface{}, e *error) { *e = fmt.Errorf("%v", v) }
-
-type must struct{}
-
-func (must) String(s string, err error) string {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-func (must) Int(s int64, err error) int64 {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-func (must) Uint(s uint64, err error) uint64 {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-func (must) Float(s float64, err error) float64 {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-
-// xdebugf prints the message in red on the terminal.
-// Use it in place of fmt.Printf (which it calls internally)
-func xdebugf(pattern string, args ...interface{}) {
-	var delim string
-	if len(pattern) > 0 && pattern[len(pattern)-1] != '\n' {
-		delim = "\n"
-	}
-	fmt.Printf("\033[1;31m"+pattern+delim+"\033[0m", args...)
-}
-
-// func isImmutableKind(k reflect.Kind) (v bool) {
-// 	return false ||
-// 		k == reflect.Int ||
-// 		k == reflect.Int8 ||
-// 		k == reflect.Int16 ||
-// 		k == reflect.Int32 ||
-// 		k == reflect.Int64 ||
-// 		k == reflect.Uint ||
-// 		k == reflect.Uint8 ||
-// 		k == reflect.Uint16 ||
-// 		k == reflect.Uint32 ||
-// 		k == reflect.Uint64 ||
-// 		k == reflect.Uintptr ||
-// 		k == reflect.Float32 ||
-// 		k == reflect.Float64 ||
-// 		k == reflect.Bool ||
-// 		k == reflect.String
-// }
-
-// func timeLocUTCName(tzint int16) string {
-// 	if tzint == 0 {
-// 		return "UTC"
-// 	}
-// 	var tzname = []byte("UTC+00:00")
-// 	//tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
-// 	//tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
-// 	var tzhr, tzmin int16
-// 	if tzint < 0 {
-// 		tzname[3] = '-' // (TODO: verify. this works here)
-// 		tzhr, tzmin = -tzint/60, (-tzint)%60
-// 	} else {
-// 		tzhr, tzmin = tzint/60, tzint%60
-// 	}
-// 	tzname[4] = timeDigits[tzhr/10]
-// 	tzname[5] = timeDigits[tzhr%10]
-// 	tzname[7] = timeDigits[tzmin/10]
-// 	tzname[8] = timeDigits[tzmin%10]
-// 	return string(tzname)
-// 	//return time.FixedZone(string(tzname), int(tzint)*60)
-// }
diff --git a/vendor/github.com/ugorji/go/codec/helper_internal.go b/vendor/github.com/ugorji/go/codec/helper_internal.go
index 0cbd665e2..5d0727f77 100644
--- a/vendor/github.com/ugorji/go/codec/helper_internal.go
+++ b/vendor/github.com/ugorji/go/codec/helper_internal.go
@@ -6,6 +6,74 @@ package codec
 // All non-std package dependencies live in this file,
 // so porting to different environment is easy (just update functions).
 
+import (
+	"errors"
+	"fmt"
+	"math"
+	"reflect"
+)
+
+func panicValToErr(panicVal interface{}, err *error) {
+	if panicVal == nil {
+		return
+	}
+	// case nil
+	switch xerr := panicVal.(type) {
+	case error:
+		*err = xerr
+	case string:
+		*err = errors.New(xerr)
+	default:
+		*err = fmt.Errorf("%v", panicVal)
+	}
+	return
+}
+
+func hIsEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
+	switch v.Kind() {
+	case reflect.Invalid:
+		return true
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		if deref {
+			if v.IsNil() {
+				return true
+			}
+			return hIsEmptyValue(v.Elem(), deref, checkStruct)
+		} else {
+			return v.IsNil()
+		}
+	case reflect.Struct:
+		if !checkStruct {
+			return false
+		}
+		// return true if all fields are empty. else return false.
+		// we cannot use equality check, because some fields may be maps/slices/etc
+		// and consequently the structs are not comparable.
+		// return v.Interface() == reflect.Zero(v.Type()).Interface()
+		for i, n := 0, v.NumField(); i < n; i++ {
+			if !hIsEmptyValue(v.Field(i), deref, checkStruct) {
+				return false
+			}
+		}
+		return true
+	}
+	return false
+}
+
+func isEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
+	return hIsEmptyValue(v, deref, checkStruct)
+}
+
 func pruneSignExt(v []byte, pos bool) (n int) {
 	if len(v) < 2 {
 	} else if pos && v[0] == 0 {
@@ -18,6 +86,37 @@ func pruneSignExt(v []byte, pos bool) (n int) {
 	return
 }
 
+func implementsIntf(typ, iTyp reflect.Type) (success bool, indir int8) {
+	if typ == nil {
+		return
+	}
+	rt := typ
+	// The type might be a pointer and we need to keep
+	// dereferencing to the base type until we find an implementation.
+	for {
+		if rt.Implements(iTyp) {
+			return true, indir
+		}
+		if p := rt; p.Kind() == reflect.Ptr {
+			indir++
+			if indir >= math.MaxInt8 { // insane number of indirections
+				return false, 0
+			}
+			rt = p.Elem()
+			continue
+		}
+		break
+	}
+	// No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
+	if typ.Kind() != reflect.Ptr {
+		// Not a pointer, but does the pointer work?
+		if reflect.PtrTo(typ).Implements(iTyp) {
+			return true, -1
+		}
+	}
+	return false, 0
+}
+
 // validate that this function is correct ...
 // culled from OGRE (Object-Oriented Graphics Rendering Engine)
 // function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html)
@@ -30,20 +129,21 @@ func halfFloatToFloatBits(yy uint16) (d uint32) {
 	if e == 0 {
 		if m == 0 { // plu or minus 0
 			return s << 31
+		} else { // Denormalized number -- renormalize it
+			for (m & 0x00000400) == 0 {
+				m <<= 1
+				e -= 1
+			}
+			e += 1
+			const zz uint32 = 0x0400
+			m &= ^zz
 		}
-		// Denormalized number -- renormalize it
-		for (m & 0x00000400) == 0 {
-			m <<= 1
-			e -= 1
-		}
-		e += 1
-		const zz uint32 = 0x0400
-		m &= ^zz
 	} else if e == 31 {
 		if m == 0 { // Inf
 			return (s << 31) | 0x7f800000
+		} else { // NaN
+			return (s << 31) | 0x7f800000 | (m << 13)
 		}
-		return (s << 31) | 0x7f800000 | (m << 13) // NaN
 	}
 	e = e + (127 - 15)
 	m = m << 13
@@ -119,3 +219,24 @@ func growCap(oldCap, unit, num int) (newCap int) {
 	}
 	return
 }
+
+func expandSliceValue(s reflect.Value, num int) reflect.Value {
+	if num <= 0 {
+		return s
+	}
+	l0 := s.Len()
+	l1 := l0 + num // new slice length
+	if l1 < l0 {
+		panic("ExpandSlice: slice overflow")
+	}
+	c0 := s.Cap()
+	if l1 <= c0 {
+		return s.Slice(0, l1)
+	}
+	st := s.Type()
+	c1 := growCap(c0, int(st.Elem().Size()), num)
+	s2 := reflect.MakeSlice(st, l1, c1)
+	// println("expandslicevalue: cap-old: ", c0, ", cap-new: ", c1, ", len-new: ", l1)
+	reflect.Copy(s2, s)
+	return s2
+}
diff --git a/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
index fd52690c9..8b06a0045 100644
--- a/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
+++ b/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
@@ -1,24 +1,13 @@
-// +build !go1.7 safe appengine
+// +build !unsafe
 
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
 
-import (
-	"reflect"
-	"sync/atomic"
-	"time"
-)
-
-const safeMode = true
-
 // stringView returns a view of the []byte as a string.
 // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
 // In regular safe mode, it is an allocation and copy.
-//
-// Usage: Always maintain a reference to v while result of this call is in use,
-//        and call keepAlive4BytesView(v) at point where done with view.
 func stringView(v []byte) string {
 	return string(v)
 }
@@ -26,247 +15,6 @@ func stringView(v []byte) string {
 // bytesView returns a view of the string as a []byte.
 // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
 // In regular safe mode, it is an allocation and copy.
-//
-// Usage: Always maintain a reference to v while result of this call is in use,
-//        and call keepAlive4BytesView(v) at point where done with view.
 func bytesView(v string) []byte {
 	return []byte(v)
 }
-
-func definitelyNil(v interface{}) bool {
-	// this is a best-effort option.
-	// We just return false, so we don't unnecessarily incur the cost of reflection this early.
-	return false
-}
-
-func rv2i(rv reflect.Value) interface{} {
-	return rv.Interface()
-}
-
-func rt2id(rt reflect.Type) uintptr {
-	return reflect.ValueOf(rt).Pointer()
-}
-
-func rv2rtid(rv reflect.Value) uintptr {
-	return reflect.ValueOf(rv.Type()).Pointer()
-}
-
-func i2rtid(i interface{}) uintptr {
-	return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
-}
-
-// --------------------------
-
-func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
-	switch v.Kind() {
-	case reflect.Invalid:
-		return true
-	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
-		return v.Len() == 0
-	case reflect.Bool:
-		return !v.Bool()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return v.Int() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return v.Uint() == 0
-	case reflect.Float32, reflect.Float64:
-		return v.Float() == 0
-	case reflect.Interface, reflect.Ptr:
-		if deref {
-			if v.IsNil() {
-				return true
-			}
-			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
-		}
-		return v.IsNil()
-	case reflect.Struct:
-		return isEmptyStruct(v, tinfos, deref, checkStruct)
-	}
-	return false
-}
-
-// --------------------------
-// type ptrToRvMap struct{}
-
-// func (*ptrToRvMap) init() {}
-// func (*ptrToRvMap) get(i interface{}) reflect.Value {
-// 	return reflect.ValueOf(i).Elem()
-// }
-
-// --------------------------
-type atomicTypeInfoSlice struct { // expected to be 2 words
-	v atomic.Value
-}
-
-func (x *atomicTypeInfoSlice) load() []rtid2ti {
-	i := x.v.Load()
-	if i == nil {
-		return nil
-	}
-	return i.([]rtid2ti)
-}
-
-func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
-	x.v.Store(p)
-}
-
-// --------------------------
-func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
-	rv.SetBytes(d.rawBytes())
-}
-
-func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
-	rv.SetString(d.d.DecodeString())
-}
-
-func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	rv.SetBool(d.d.DecodeBool())
-}
-
-func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	rv.Set(reflect.ValueOf(d.d.DecodeTime()))
-}
-
-func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	fv := d.d.DecodeFloat64()
-	if chkOvf.Float32(fv) {
-		d.errorf("float32 overflow: %v", fv)
-	}
-	rv.SetFloat(fv)
-}
-
-func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	rv.SetFloat(d.d.DecodeFloat64())
-}
-
-func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
-}
-
-func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 8))
-}
-
-func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 16))
-}
-
-func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 32))
-}
-
-func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(d.d.DecodeInt64())
-}
-
-func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 8))
-}
-
-func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 16))
-}
-
-func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 32))
-}
-
-func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(d.d.DecodeUint64())
-}
-
-// ----------------
-
-func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeBool(rv.Bool())
-}
-
-func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeTime(rv2i(rv).(time.Time))
-}
-
-func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeString(cUTF8, rv.String())
-}
-
-func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeFloat64(rv.Float())
-}
-
-func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeFloat32(float32(rv.Float()))
-}
-
-func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
-// //
-// // Usage: call this at point where done with the bytes view.
-// func keepAlive4BytesView(v string) {}
-
-// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
-// //
-// // Usage: call this at point where done with the string view.
-// func keepAlive4StringView(v []byte) {}
-
-// func definitelyNil(v interface{}) bool {
-// 	rv := reflect.ValueOf(v)
-// 	switch rv.Kind() {
-// 	case reflect.Invalid:
-// 		return true
-// 	case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
-// 		return rv.IsNil()
-// 	default:
-// 		return false
-// 	}
-// }
diff --git a/vendor/github.com/ugorji/go/codec/helper_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_unsafe.go
index e3df60abe..0f596c71a 100644
--- a/vendor/github.com/ugorji/go/codec/helper_unsafe.go
+++ b/vendor/github.com/ugorji/go/codec/helper_unsafe.go
@@ -1,639 +1,49 @@
-// +build !safe
-// +build !appengine
-// +build go1.7
+// +build unsafe
 
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
 
 import (
-	"reflect"
-	"sync/atomic"
-	"time"
 	"unsafe"
 )
 
 // This file has unsafe variants of some helper methods.
-// NOTE: See helper_not_unsafe.go for the usage information.
-
-// var zeroRTv [4]uintptr
-
-const safeMode = false
-const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
 
 type unsafeString struct {
-	Data unsafe.Pointer
+	Data uintptr
 	Len  int
 }
 
 type unsafeSlice struct {
-	Data unsafe.Pointer
+	Data uintptr
 	Len  int
 	Cap  int
 }
 
-type unsafeIntf struct {
-	typ  unsafe.Pointer
-	word unsafe.Pointer
-}
-
-type unsafeReflectValue struct {
-	typ  unsafe.Pointer
-	ptr  unsafe.Pointer
-	flag uintptr
-}
-
+// stringView returns a view of the []byte as a string.
+// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
+// In regular safe mode, it is an allocation and copy.
 func stringView(v []byte) string {
 	if len(v) == 0 {
 		return ""
 	}
+
 	bx := (*unsafeSlice)(unsafe.Pointer(&v))
-	return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
+	sx := unsafeString{bx.Data, bx.Len}
+	return *(*string)(unsafe.Pointer(&sx))
 }
 
+// bytesView returns a view of the string as a []byte.
+// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
+// In regular safe mode, it is an allocation and copy.
 func bytesView(v string) []byte {
 	if len(v) == 0 {
 		return zeroByteSlice
 	}
-	sx := (*unsafeString)(unsafe.Pointer(&v))
-	return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
-}
-
-func definitelyNil(v interface{}) bool {
-	// There is no global way of checking if an interface is nil.
-	// For true references (map, ptr, func, chan), you can just look
-	// at the word of the interface. However, for slices, you have to dereference
-	// the word, and get a pointer to the 3-word interface value.
-	//
-	// However, the following are cheap calls
-	// - TypeOf(interface): cheap 2-line call.
-	// - ValueOf(interface{}): expensive
-	// - type.Kind: cheap call through an interface
-	// - Value.Type(): cheap call
-	//                 except it's a method value (e.g. r.Read, which implies that it is a Func)
-
-	return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
-}
-
-func rv2i(rv reflect.Value) interface{} {
-	// TODO: consider a more generally-known optimization for reflect.Value ==> Interface
-	//
-	// Currently, we use this fragile method that taps into implememtation details from
-	// the source go stdlib reflect/value.go, and trims the implementation.
-
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
-	var ptr unsafe.Pointer
-	if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
-		ptr = *(*unsafe.Pointer)(urv.ptr)
-	} else {
-		ptr = urv.ptr
-	}
-	return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
-}
-
-func rt2id(rt reflect.Type) uintptr {
-	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
-}
-
-func rv2rtid(rv reflect.Value) uintptr {
-	return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
-}
-
-func i2rtid(i interface{}) uintptr {
-	return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
-}
-
-// --------------------------
-
-func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
-	if urv.flag == 0 {
-		return true
-	}
-	switch v.Kind() {
-	case reflect.Invalid:
-		return true
-	case reflect.String:
-		return (*unsafeString)(urv.ptr).Len == 0
-	case reflect.Slice:
-		return (*unsafeSlice)(urv.ptr).Len == 0
-	case reflect.Bool:
-		return !*(*bool)(urv.ptr)
-	case reflect.Int:
-		return *(*int)(urv.ptr) == 0
-	case reflect.Int8:
-		return *(*int8)(urv.ptr) == 0
-	case reflect.Int16:
-		return *(*int16)(urv.ptr) == 0
-	case reflect.Int32:
-		return *(*int32)(urv.ptr) == 0
-	case reflect.Int64:
-		return *(*int64)(urv.ptr) == 0
-	case reflect.Uint:
-		return *(*uint)(urv.ptr) == 0
-	case reflect.Uint8:
-		return *(*uint8)(urv.ptr) == 0
-	case reflect.Uint16:
-		return *(*uint16)(urv.ptr) == 0
-	case reflect.Uint32:
-		return *(*uint32)(urv.ptr) == 0
-	case reflect.Uint64:
-		return *(*uint64)(urv.ptr) == 0
-	case reflect.Uintptr:
-		return *(*uintptr)(urv.ptr) == 0
-	case reflect.Float32:
-		return *(*float32)(urv.ptr) == 0
-	case reflect.Float64:
-		return *(*float64)(urv.ptr) == 0
-	case reflect.Interface:
-		isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
-		if deref {
-			if isnil {
-				return true
-			}
-			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
-		}
-		return isnil
-	case reflect.Ptr:
-		// isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
-		isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
-		if deref {
-			if isnil {
-				return true
-			}
-			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
-		}
-		return isnil
-	case reflect.Struct:
-		return isEmptyStruct(v, tinfos, deref, checkStruct)
-	case reflect.Map, reflect.Array, reflect.Chan:
-		return v.Len() == 0
-	}
-	return false
-}
-
-// --------------------------
-
-// atomicTypeInfoSlice contains length and pointer to the array for a slice.
-// It is expected to be 2 words.
-//
-// Previously, we atomically loaded and stored the length and array pointer separately,
-// which could lead to some races.
-// We now just atomically store and load the pointer to the value directly.
-
-type atomicTypeInfoSlice struct { // expected to be 2 words
-	l int            // length of the data array (must be first in struct, for 64-bit alignment necessary for 386)
-	v unsafe.Pointer // data array - Pointer (not uintptr) to maintain GC reference
-}
-
-func (x *atomicTypeInfoSlice) load() []rtid2ti {
-	xp := unsafe.Pointer(x)
-	x2 := *(*atomicTypeInfoSlice)(atomic.LoadPointer(&xp))
-	if x2.l == 0 {
-		return nil
-	}
-	return *(*[]rtid2ti)(unsafe.Pointer(&unsafeSlice{Data: x2.v, Len: x2.l, Cap: x2.l}))
-}
-
-func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
-	s := (*unsafeSlice)(unsafe.Pointer(&p))
-	xp := unsafe.Pointer(x)
-	atomic.StorePointer(&xp, unsafe.Pointer(&atomicTypeInfoSlice{l: s.Len, v: s.Data}))
-}
-
-// --------------------------
-func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*[]byte)(urv.ptr) = d.rawBytes()
-}
-
-func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*string)(urv.ptr) = d.d.DecodeString()
-}
-
-func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*bool)(urv.ptr) = d.d.DecodeBool()
-}
-
-func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*time.Time)(urv.ptr) = d.d.DecodeTime()
-}
-
-func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	fv := d.d.DecodeFloat64()
-	if chkOvf.Float32(fv) {
-		d.errorf("float32 overflow: %v", fv)
-	}
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*float32)(urv.ptr) = float32(fv)
-}
-
-func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*float64)(urv.ptr) = d.d.DecodeFloat64()
-}
-
-func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
-}
-
-func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
-}
-
-func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
-}
-
-func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
-}
-
-func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int64)(urv.ptr) = d.d.DecodeInt64()
-}
-
-func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
-}
-
-func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
-}
-
-func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
-}
-
-func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint64)(urv.ptr) = d.d.DecodeUint64()
-}
-
-// ------------
-
-func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeBool(*(*bool)(v.ptr))
-}
-
-func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeTime(*(*time.Time)(v.ptr))
-}
-
-func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeString(cUTF8, *(*string)(v.ptr))
-}
-
-func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeFloat64(*(*float64)(v.ptr))
-}
-
-func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeFloat32(*(*float32)(v.ptr))
-}
-
-func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int)(v.ptr)))
-}
-
-func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int8)(v.ptr)))
-}
-
-func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int16)(v.ptr)))
-}
-
-func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int32)(v.ptr)))
-}
-
-func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int64)(v.ptr)))
-}
-
-func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
-}
-
-func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
-}
-
-func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
-}
-
-func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
-}
-
-func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
-}
 
-func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
+	sx := (*unsafeString)(unsafe.Pointer(&v))
+	bx := unsafeSlice{sx.Data, sx.Len, sx.Len}
+	return *(*[]byte)(unsafe.Pointer(&bx))
 }
-
-// ------------
-
-// func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// if urv.flag&unsafeFlagIndir != 0 {
-// 	// 	urv.ptr = *(*unsafe.Pointer)(urv.ptr)
-// 	// }
-// 	*(*[]byte)(urv.ptr) = d.rawBytes()
-// }
-
-// func rv0t(rt reflect.Type) reflect.Value {
-// 	ut := (*unsafeIntf)(unsafe.Pointer(&rt))
-// 	// we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
-// 	uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
-// 	return *(*reflect.Value)(unsafe.Pointer(&uv})
-// }
-
-// func rv2i(rv reflect.Value) interface{} {
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
-// 	var ptr unsafe.Pointer
-// 	// kk := reflect.Kind(urv.flag & (1<<5 - 1))
-// 	// if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
-// 	if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
-// 		ptr = *(*unsafe.Pointer)(urv.ptr)
-// 	} else {
-// 		ptr = urv.ptr
-// 	}
-// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
-// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// }
-
-// func definitelyNil(v interface{}) bool {
-// 	var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
-// 	if ui.word == nil {
-// 		return true
-// 	}
-// 	var tk = reflect.TypeOf(v).Kind()
-// 	return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
-// 	fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
-// 	v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
-// }
-
-// func keepAlive4BytesView(v string) {
-// 	runtime.KeepAlive(v)
-// }
-
-// func keepAlive4StringView(v []byte) {
-// 	runtime.KeepAlive(v)
-// }
-
-// func rt2id(rt reflect.Type) uintptr {
-// 	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
-// 	// var i interface{} = rt
-// 	// // ui := (*unsafeIntf)(unsafe.Pointer(&i))
-// 	// return ((*unsafeIntf)(unsafe.Pointer(&i))).word
-// }
-
-// func rv2i(rv reflect.Value) interface{} {
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// non-reference type: already indir
-// 	// reference type: depend on flagIndir property ('cos maybe was double-referenced)
-// 	// const (unsafeRvFlagKindMask    = 1<<5 - 1 , unsafeRvFlagIndir       = 1 << 7 )
-// 	// rvk := reflect.Kind(urv.flag & (1<<5 - 1))
-// 	// if (rvk == reflect.Chan ||
-// 	// 	rvk == reflect.Func ||
-// 	// 	rvk == reflect.Interface ||
-// 	// 	rvk == reflect.Map ||
-// 	// 	rvk == reflect.Ptr ||
-// 	// 	rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
-// 	// 	fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
-// 	// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	// }
-// 	if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
-// 		// fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	}
-// 	// fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
-// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// }
-
-// const (
-// 	unsafeRvFlagKindMask    = 1<<5 - 1
-// 	unsafeRvKindDirectIface = 1 << 5
-// 	unsafeRvFlagIndir       = 1 << 7
-// 	unsafeRvFlagAddr        = 1 << 8
-// 	unsafeRvFlagMethod      = 1 << 9
-
-// 	_USE_RV_INTERFACE bool = false
-// 	_UNSAFE_RV_DEBUG       = true
-// )
-
-// type unsafeRtype struct {
-// 	_    [2]uintptr
-// 	_    uint32
-// 	_    uint8
-// 	_    uint8
-// 	_    uint8
-// 	kind uint8
-// 	_    [2]uintptr
-// 	_    int32
-// }
-
-// func _rv2i(rv reflect.Value) interface{} {
-// 	// Note: From use,
-// 	//   - it's never an interface
-// 	//   - the only calls here are for ifaceIndir types.
-// 	//     (though that conditional is wrong)
-// 	//     To know for sure, we need the value of t.kind (which is not exposed).
-// 	//
-// 	// Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
-// 	//    - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
-// 	//    - Type Direct,   Value indirect: ==> map???
-// 	//    - Type Direct,   Value direct:   ==> pointers, unsafe.Pointer, func, chan, map
-// 	//
-// 	// TRANSLATES TO:
-// 	//    if typeIndirect { } else if valueIndirect { } else { }
-// 	//
-// 	// Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
-
-// 	if _USE_RV_INTERFACE {
-// 		return rv.Interface()
-// 	}
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-
-// 	// if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
-// 	// 	println("***** IS flag method or interface: delegating to rv.Interface()")
-// 	// 	return rv.Interface()
-// 	// }
-
-// 	// if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
-// 	// 	println("***** IS Interface: delegate to rv.Interface")
-// 	// 	return rv.Interface()
-// 	// }
-// 	// if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
-// 	// 	if urv.flag&unsafeRvFlagAddr == 0 {
-// 	// 		println("***** IS ifaceIndir typ")
-// 	// 		// ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
-// 	// 		// return *(*interface{})(unsafe.Pointer(&ui))
-// 	// 		// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 	// 	}
-// 	// } else if urv.flag&unsafeRvFlagIndir != 0 {
-// 	// 	println("***** IS flagindir")
-// 	// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	// } else {
-// 	// 	println("***** NOT flagindir")
-// 	// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 	// }
-// 	// println("***** default: delegate to rv.Interface")
-
-// 	urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
-// 	if _UNSAFE_RV_DEBUG {
-// 		fmt.Printf(">>>> start: %v: ", rv.Type())
-// 		fmt.Printf("%v - %v\n", *urv, *urt)
-// 	}
-// 	if urt.kind&unsafeRvKindDirectIface == 0 {
-// 		if _UNSAFE_RV_DEBUG {
-// 			fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
-// 		}
-// 		// println("***** IS ifaceIndir typ")
-// 		// if true || urv.flag&unsafeRvFlagAddr == 0 {
-// 		// 	// println("    ***** IS NOT addr")
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 		// }
-// 	} else if urv.flag&unsafeRvFlagIndir != 0 {
-// 		if _UNSAFE_RV_DEBUG {
-// 			fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
-// 		}
-// 		// println("***** IS flagindir")
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	} else {
-// 		if _UNSAFE_RV_DEBUG {
-// 			fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
-// 		}
-// 		// println("***** NOT flagindir")
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 	}
-// 	// println("***** default: delegating to rv.Interface()")
-// 	// return rv.Interface()
-// }
-
-// var staticM0 = make(map[string]uint64)
-// var staticI0 = (int32)(-5)
-
-// func staticRv2iTest() {
-// 	i0 := (int32)(-5)
-// 	m0 := make(map[string]uint16)
-// 	m0["1"] = 1
-// 	for _, i := range []interface{}{
-// 		(int)(7),
-// 		(uint)(8),
-// 		(int16)(-9),
-// 		(uint16)(19),
-// 		(uintptr)(77),
-// 		(bool)(true),
-// 		float32(-32.7),
-// 		float64(64.9),
-// 		complex(float32(19), 5),
-// 		complex(float64(-32), 7),
-// 		[4]uint64{1, 2, 3, 4},
-// 		(chan<- int)(nil), // chan,
-// 		rv2i,              // func
-// 		io.Writer(ioutil.Discard),
-// 		make(map[string]uint),
-// 		(map[string]uint)(nil),
-// 		staticM0,
-// 		m0,
-// 		&m0,
-// 		i0,
-// 		&i0,
-// 		&staticI0,
-// 		&staticM0,
-// 		[]uint32{6, 7, 8},
-// 		"abc",
-// 		Raw{},
-// 		RawExt{},
-// 		&Raw{},
-// 		&RawExt{},
-// 		unsafe.Pointer(&i0),
-// 	} {
-// 		i2 := rv2i(reflect.ValueOf(i))
-// 		eq := reflect.DeepEqual(i, i2)
-// 		fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
-// 	}
-// 	// os.Exit(0)
-// }
-
-// func init() {
-// 	staticRv2iTest()
-// }
-
-// func rv2i(rv reflect.Value) interface{} {
-// 	if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
-// 		return rv.Interface()
-// 	}
-// 	// var i interface{}
-// 	// ui := (*unsafeIntf)(unsafe.Pointer(&i))
-// 	var ui unsafeIntf
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
-// 	if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
-// 		if urv.flag&unsafeRvFlagAddr != 0 {
-// 			println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
-// 			return rv.Interface()
-// 		}
-// 		println("****** indirect type/kind")
-// 		ui.word = urv.ptr
-// 	} else if urv.flag&unsafeRvFlagIndir != 0 {
-// 		println("****** unsafe rv flag indir")
-// 		ui.word = *(*unsafe.Pointer)(urv.ptr)
-// 	} else {
-// 		println("****** default: assign prt to word directly")
-// 		ui.word = urv.ptr
-// 	}
-// 	// ui.word = urv.ptr
-// 	ui.typ = urv.typ
-// 	// fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
-// 	// fmt.Printf("(binary)   ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
-// 	return *(*interface{})(unsafe.Pointer(&ui))
-// 	// return i
-// }
diff --git a/vendor/github.com/ugorji/go/codec/json.go b/vendor/github.com/ugorji/go/codec/json.go
index bdd199663..463cae3db 100644
--- a/vendor/github.com/ugorji/go/codec/json.go
+++ b/vendor/github.com/ugorji/go/codec/json.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
@@ -17,6 +17,16 @@ package codec
 // Note:
 //   - we cannot use strconv.Quote and strconv.Unquote because json quotes/unquotes differently.
 //     We implement it here.
+//   - Also, strconv.ParseXXX for floats and integers
+//     - only works on strings resulting in unnecessary allocation and []byte-string conversion.
+//     - it does a lot of redundant checks, because json numbers are simpler that what it supports.
+//   - We parse numbers (floats and integers) directly here.
+//     We only delegate parsing floats if it is a hairy float which could cause a loss of precision.
+//     In that case, we delegate to strconv.ParseFloat.
+//
+// Note:
+//   - encode does not beautify. There is no whitespace when encoding.
+//   - rpc calls which take single integer arguments or write single numeric arguments will need care.
 
 // Top-level methods of json(End|Dec)Driver (which are implementations of (en|de)cDriver
 // MUST not call one-another.
@@ -24,41 +34,42 @@ package codec
 import (
 	"bytes"
 	"encoding/base64"
-	"math"
+	"fmt"
 	"reflect"
 	"strconv"
-	"time"
-	"unicode"
 	"unicode/utf16"
 	"unicode/utf8"
 )
 
 //--------------------------------
 
-var jsonLiterals = [...]byte{
-	'"', 't', 'r', 'u', 'e', '"',
-	'"', 'f', 'a', 'l', 's', 'e', '"',
-	'"', 'n', 'u', 'l', 'l', '"',
-}
+var (
+	jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'}
 
-const (
-	jsonLitTrueQ  = 0
-	jsonLitTrue   = 1
-	jsonLitFalseQ = 6
-	jsonLitFalse  = 7
-	jsonLitNullQ  = 13
-	jsonLitNull   = 14
-)
+	jsonFloat64Pow10 = [...]float64{
+		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+		1e20, 1e21, 1e22,
+	}
 
-const (
-	jsonU4Chk2 = '0'
-	jsonU4Chk1 = 'a' - 10
-	jsonU4Chk0 = 'A' - 10
+	jsonUint64Pow10 = [...]uint64{
+		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+	}
 
-	jsonScratchArrayLen = 64
+	// jsonTabs and jsonSpaces are used as caches for indents
+	jsonTabs, jsonSpaces string
 )
 
 const (
+	// jsonUnreadAfterDecNum controls whether we unread after decoding a number.
+	//
+	// instead of unreading, just update d.tok (iff it's not a whitespace char)
+	// However, doing this means that we may HOLD onto some data which belongs to another stream.
+	// Thus, it is safest to unread the data when done.
+	// keep behind a constant flag for now.
+	jsonUnreadAfterDecNum = true
+
 	// If !jsonValidateSymbols, decoding will be faster, by skipping some checks:
 	//   - If we see first character of null, false or true,
 	//     do not validate subsequent characters.
@@ -67,156 +78,48 @@ const (
 	// P.S. Do not expect a significant decoding boost from this.
 	jsonValidateSymbols = true
 
-	jsonSpacesOrTabsLen = 128
+	// if jsonTruncateMantissa, truncate mantissa if trailing 0's.
+	// This is important because it could allow some floats to be decoded without
+	// deferring to strconv.ParseFloat.
+	jsonTruncateMantissa = true
 
-	jsonAlwaysReturnInternString = false
-)
+	// if mantissa >= jsonNumUintCutoff before multiplying by 10, this is an overflow
+	jsonNumUintCutoff = (1<<64-1)/uint64(10) + 1 // cutoff64(base)
 
-var (
-	// jsonTabs and jsonSpaces are used as caches for indents
-	jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
+	// if mantissa >= jsonNumUintMaxVal, this is an overflow
+	jsonNumUintMaxVal = 1<<uint64(64) - 1
 
-	jsonCharHtmlSafeSet   bitset128
-	jsonCharSafeSet       bitset128
-	jsonCharWhitespaceSet bitset256
-	jsonNumSet            bitset256
+	// jsonNumDigitsUint64Largest = 19
+
+	jsonSpacesOrTabsLen = 128
 )
 
 func init() {
+	var bs [jsonSpacesOrTabsLen]byte
 	for i := 0; i < jsonSpacesOrTabsLen; i++ {
-		jsonSpaces[i] = ' '
-		jsonTabs[i] = '\t'
-	}
-
-	// populate the safe values as true: note: ASCII control characters are (0-31)
-	// jsonCharSafeSet:     all true except (0-31) " \
-	// jsonCharHtmlSafeSet: all true except (0-31) " \ < > &
-	var i byte
-	for i = 32; i < utf8.RuneSelf; i++ {
-		switch i {
-		case '"', '\\':
-		case '<', '>', '&':
-			jsonCharSafeSet.set(i) // = true
-		default:
-			jsonCharSafeSet.set(i)
-			jsonCharHtmlSafeSet.set(i)
-		}
-	}
-	for i = 0; i <= utf8.RuneSelf; i++ {
-		switch i {
-		case ' ', '\t', '\r', '\n':
-			jsonCharWhitespaceSet.set(i)
-		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-':
-			jsonNumSet.set(i)
-		}
-	}
-}
-
-// ----------------
-
-type jsonEncDriverTypical struct {
-	w encWriter
-	// w  *encWriterSwitch
-	b  *[jsonScratchArrayLen]byte
-	tw bool // term white space
-	c  containerState
-}
-
-func (e *jsonEncDriverTypical) typical() {}
-
-func (e *jsonEncDriverTypical) reset(ee *jsonEncDriver) {
-	e.w = ee.ew
-	// e.w = &ee.e.encWriterSwitch
-	e.b = &ee.b
-	e.tw = ee.h.TermWhitespace
-	e.c = 0
-}
-
-func (e *jsonEncDriverTypical) WriteArrayStart(length int) {
-	e.w.writen1('[')
-	e.c = containerArrayStart
-}
-
-func (e *jsonEncDriverTypical) WriteArrayElem() {
-	if e.c != containerArrayStart {
-		e.w.writen1(',')
-	}
-	e.c = containerArrayElem
-}
-
-func (e *jsonEncDriverTypical) WriteArrayEnd() {
-	e.w.writen1(']')
-	e.c = containerArrayEnd
-}
-
-func (e *jsonEncDriverTypical) WriteMapStart(length int) {
-	e.w.writen1('{')
-	e.c = containerMapStart
-}
-
-func (e *jsonEncDriverTypical) WriteMapElemKey() {
-	if e.c != containerMapStart {
-		e.w.writen1(',')
+		bs[i] = ' '
 	}
-	e.c = containerMapKey
-}
-
-func (e *jsonEncDriverTypical) WriteMapElemValue() {
-	e.w.writen1(':')
-	e.c = containerMapValue
-}
-
-func (e *jsonEncDriverTypical) WriteMapEnd() {
-	e.w.writen1('}')
-	e.c = containerMapEnd
-}
-
-func (e *jsonEncDriverTypical) EncodeBool(b bool) {
-	if b {
-		e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
-	} else {
-		e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
-	}
-}
-
-func (e *jsonEncDriverTypical) EncodeFloat64(f float64) {
-	fmt, prec := jsonFloatStrconvFmtPrec(f)
-	e.w.writeb(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
-}
-
-func (e *jsonEncDriverTypical) EncodeInt(v int64) {
-	e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
-}
-
-func (e *jsonEncDriverTypical) EncodeUint(v uint64) {
-	e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
-}
-
-func (e *jsonEncDriverTypical) EncodeFloat32(f float32) {
-	e.EncodeFloat64(float64(f))
-}
+	jsonSpaces = string(bs[:])
 
-func (e *jsonEncDriverTypical) atEndOfEncode() {
-	if e.tw {
-		e.w.writen1(' ')
+	for i := 0; i < jsonSpacesOrTabsLen; i++ {
+		bs[i] = '\t'
 	}
+	jsonTabs = string(bs[:])
 }
 
-// ----------------
-
-type jsonEncDriverGeneric struct {
-	w encWriter // encWriter // *encWriterSwitch
-	b *[jsonScratchArrayLen]byte
-	c containerState
-	// ds string // indent string
-	di int8    // indent per
-	d  bool    // indenting?
-	dt bool    // indent using tabs
-	dl uint16  // indent level
-	ks bool    // map key as string
-	is byte    // integer as string
-	tw bool    // term white space
-	_  [7]byte // padding
+type jsonEncDriver struct {
+	e  *Encoder
+	w  encWriter
+	h  *JsonHandle
+	b  [64]byte // scratch
+	bs []byte   // scratch
+	se setExtWrapper
+	ds string // indent string
+	dl uint16 // indent level
+	dt bool   // indent using tabs
+	d  bool   // indent
+	c  containerState
+	noBuiltInTypes
 }
 
 // indent is done as below:
@@ -224,227 +127,115 @@ type jsonEncDriverGeneric struct {
 //   - newline and indent are added before each ending,
 //     except there was no entry (so we can have {} or [])
 
-func (e *jsonEncDriverGeneric) reset(ee *jsonEncDriver) {
-	e.w = ee.ew
-	e.b = &ee.b
-	e.tw = ee.h.TermWhitespace
-	e.c = 0
-	e.d, e.dt, e.dl, e.di = false, false, 0, 0
-	h := ee.h
-	if h.Indent > 0 {
-		e.d = true
-		e.di = int8(h.Indent)
-	} else if h.Indent < 0 {
-		e.d = true
-		e.dt = true
-		e.di = int8(-h.Indent)
-	}
-	e.ks = h.MapKeyAsString
-	e.is = h.IntegerAsString
-}
-
-func (e *jsonEncDriverGeneric) WriteArrayStart(length int) {
-	if e.d {
-		e.dl++
-	}
-	e.w.writen1('[')
-	e.c = containerArrayStart
-}
-
-func (e *jsonEncDriverGeneric) WriteArrayElem() {
-	if e.c != containerArrayStart {
-		e.w.writen1(',')
-	}
-	if e.d {
-		e.writeIndent()
-	}
-	e.c = containerArrayElem
-}
-
-func (e *jsonEncDriverGeneric) WriteArrayEnd() {
-	if e.d {
-		e.dl--
-		if e.c != containerArrayStart {
-			e.writeIndent()
-		}
-	}
-	e.w.writen1(']')
-	e.c = containerArrayEnd
-}
-
-func (e *jsonEncDriverGeneric) WriteMapStart(length int) {
-	if e.d {
-		e.dl++
-	}
-	e.w.writen1('{')
-	e.c = containerMapStart
-}
-
-func (e *jsonEncDriverGeneric) WriteMapElemKey() {
-	if e.c != containerMapStart {
-		e.w.writen1(',')
-	}
-	if e.d {
-		e.writeIndent()
-	}
-	e.c = containerMapKey
-}
-
-func (e *jsonEncDriverGeneric) WriteMapElemValue() {
-	if e.d {
-		e.w.writen2(':', ' ')
-	} else {
-		e.w.writen1(':')
-	}
-	e.c = containerMapValue
-}
-
-func (e *jsonEncDriverGeneric) WriteMapEnd() {
-	if e.d {
-		e.dl--
+func (e *jsonEncDriver) sendContainerState(c containerState) {
+	// determine whether to output separators
+	if c == containerMapKey {
 		if e.c != containerMapStart {
+			e.w.writen1(',')
+		}
+		if e.d {
 			e.writeIndent()
 		}
-	}
-	e.w.writen1('}')
-	e.c = containerMapEnd
-}
-
-func (e *jsonEncDriverGeneric) writeIndent() {
-	e.w.writen1('\n')
-	x := int(e.di) * int(e.dl)
-	if e.dt {
-		for x > jsonSpacesOrTabsLen {
-			e.w.writeb(jsonTabs[:])
-			x -= jsonSpacesOrTabsLen
+	} else if c == containerMapValue {
+		if e.d {
+			e.w.writen2(':', ' ')
+		} else {
+			e.w.writen1(':')
 		}
-		e.w.writeb(jsonTabs[:x])
-	} else {
-		for x > jsonSpacesOrTabsLen {
-			e.w.writeb(jsonSpaces[:])
-			x -= jsonSpacesOrTabsLen
+	} else if c == containerMapEnd {
+		if e.d {
+			e.dl--
+			if e.c != containerMapStart {
+				e.writeIndent()
+			}
+		}
+		e.w.writen1('}')
+	} else if c == containerArrayElem {
+		if e.c != containerArrayStart {
+			e.w.writen1(',')
+		}
+		if e.d {
+			e.writeIndent()
+		}
+	} else if c == containerArrayEnd {
+		if e.d {
+			e.dl--
+			if e.c != containerArrayStart {
+				e.writeIndent()
+			}
 		}
-		e.w.writeb(jsonSpaces[:x])
+		e.w.writen1(']')
 	}
+	e.c = c
 }
 
-func (e *jsonEncDriverGeneric) EncodeBool(b bool) {
-	if e.ks && e.c == containerMapKey {
-		if b {
-			e.w.writeb(jsonLiterals[jsonLitTrueQ : jsonLitTrueQ+6])
+func (e *jsonEncDriver) writeIndent() {
+	e.w.writen1('\n')
+	if x := len(e.ds) * int(e.dl); x <= jsonSpacesOrTabsLen {
+		if e.dt {
+			e.w.writestr(jsonTabs[:x])
 		} else {
-			e.w.writeb(jsonLiterals[jsonLitFalseQ : jsonLitFalseQ+7])
+			e.w.writestr(jsonSpaces[:x])
 		}
 	} else {
-		if b {
-			e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
-		} else {
-			e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
+		for i := uint16(0); i < e.dl; i++ {
+			e.w.writestr(e.ds)
 		}
 	}
 }
 
-func (e *jsonEncDriverGeneric) EncodeFloat64(f float64) {
-	// instead of using 'g', specify whether to use 'e' or 'f'
-	fmt, prec := jsonFloatStrconvFmtPrec(f)
-
-	var blen int
-	if e.ks && e.c == containerMapKey {
-		blen = 2 + len(strconv.AppendFloat(e.b[1:1], f, fmt, prec, 64))
-		e.b[0] = '"'
-		e.b[blen-1] = '"'
-	} else {
-		blen = len(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
-	}
-	e.w.writeb(e.b[:blen])
+func (e *jsonEncDriver) EncodeNil() {
+	e.w.writeb(jsonLiterals[9:13]) // null
 }
 
-func (e *jsonEncDriverGeneric) EncodeInt(v int64) {
-	x := e.is
-	if x == 'A' || x == 'L' && (v > 1<<53 || v < -(1<<53)) || (e.ks && e.c == containerMapKey) {
-		blen := 2 + len(strconv.AppendInt(e.b[1:1], v, 10))
-		e.b[0] = '"'
-		e.b[blen-1] = '"'
-		e.w.writeb(e.b[:blen])
-		return
+func (e *jsonEncDriver) EncodeBool(b bool) {
+	if b {
+		e.w.writeb(jsonLiterals[0:4]) // true
+	} else {
+		e.w.writeb(jsonLiterals[4:9]) // false
 	}
-	e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
 }
 
-func (e *jsonEncDriverGeneric) EncodeUint(v uint64) {
-	x := e.is
-	if x == 'A' || x == 'L' && v > 1<<53 || (e.ks && e.c == containerMapKey) {
-		blen := 2 + len(strconv.AppendUint(e.b[1:1], v, 10))
-		e.b[0] = '"'
-		e.b[blen-1] = '"'
-		e.w.writeb(e.b[:blen])
-		return
-	}
-	e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
+func (e *jsonEncDriver) EncodeFloat32(f float32) {
+	e.encodeFloat(float64(f), 32)
 }
 
-func (e *jsonEncDriverGeneric) EncodeFloat32(f float32) {
-	// e.encodeFloat(float64(f), 32)
-	// always encode all floats as IEEE 64-bit floating point.
-	// It also ensures that we can decode in full precision even if into a float32,
-	// as what is written is always to float64 precision.
-	e.EncodeFloat64(float64(f))
+func (e *jsonEncDriver) EncodeFloat64(f float64) {
+	// e.w.writestr(strconv.FormatFloat(f, 'E', -1, 64))
+	e.encodeFloat(f, 64)
 }
 
-func (e *jsonEncDriverGeneric) atEndOfEncode() {
-	if e.tw {
-		if e.d {
-			e.w.writen1('\n')
-		} else {
-			e.w.writen1(' ')
-		}
+func (e *jsonEncDriver) encodeFloat(f float64, numbits int) {
+	x := strconv.AppendFloat(e.b[:0], f, 'G', -1, numbits)
+	e.w.writeb(x)
+	if bytes.IndexByte(x, 'E') == -1 && bytes.IndexByte(x, '.') == -1 {
+		e.w.writen2('.', '0')
 	}
 }
 
-// --------------------
-
-type jsonEncDriver struct {
-	noBuiltInTypes
-	e  *Encoder
-	h  *JsonHandle
-	ew encWriter // encWriter // *encWriterSwitch
-	se extWrapper
-	// ---- cpu cache line boundary?
-	bs []byte // scratch
-	// ---- cpu cache line boundary?
-	b [jsonScratchArrayLen]byte // scratch (encode time,
-}
-
-func (e *jsonEncDriver) EncodeNil() {
-	// We always encode nil as just null (never in quotes)
-	// This allows us to easily decode if a nil in the json stream
-	// ie if initial token is n.
-	e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
-
-	// if e.h.MapKeyAsString && e.c == containerMapKey {
-	// 	e.ew.writeb(jsonLiterals[jsonLitNullQ : jsonLitNullQ+6])
-	// } else {
-	// 	e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
-	// }
+func (e *jsonEncDriver) EncodeInt(v int64) {
+	if x := e.h.IntegerAsString; x == 'A' || x == 'L' && (v > 1<<53 || v < -(1<<53)) {
+		e.w.writen1('"')
+		e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
+		e.w.writen1('"')
+		return
+	}
+	e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
 }
 
-func (e *jsonEncDriver) EncodeTime(t time.Time) {
-	// Do NOT use MarshalJSON, as it allocates internally.
-	// instead, we call AppendFormat directly, using our scratch buffer (e.b)
-	if t.IsZero() {
-		e.EncodeNil()
-	} else {
-		e.b[0] = '"'
-		b := t.AppendFormat(e.b[1:1], time.RFC3339Nano)
-		e.b[len(b)+1] = '"'
-		e.ew.writeb(e.b[:len(b)+2])
+func (e *jsonEncDriver) EncodeUint(v uint64) {
+	if x := e.h.IntegerAsString; x == 'A' || x == 'L' && v > 1<<53 {
+		e.w.writen1('"')
+		e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
+		e.w.writen1('"')
+		return
 	}
-	// v, err := t.MarshalJSON(); if err != nil { e.e.error(err) } e.ew.writeb(v)
+	e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
 }
 
 func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
 	if v := ext.ConvertExt(rv); v == nil {
-		e.EncodeNil()
+		e.w.writeb(jsonLiterals[9:13]) // null // e.EncodeNil()
 	} else {
 		en.encode(v)
 	}
@@ -453,61 +244,76 @@ func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Enco
 func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
 	// only encodes re.Value (never re.Data)
 	if re.Value == nil {
-		e.EncodeNil()
+		e.w.writeb(jsonLiterals[9:13]) // null // e.EncodeNil()
 	} else {
 		en.encode(re.Value)
 	}
 }
 
+func (e *jsonEncDriver) EncodeArrayStart(length int) {
+	if e.d {
+		e.dl++
+	}
+	e.w.writen1('[')
+	e.c = containerArrayStart
+}
+
+func (e *jsonEncDriver) EncodeMapStart(length int) {
+	if e.d {
+		e.dl++
+	}
+	e.w.writen1('{')
+	e.c = containerMapStart
+}
+
 func (e *jsonEncDriver) EncodeString(c charEncoding, v string) {
+	// e.w.writestr(strconv.Quote(v))
+	e.quoteStr(v)
+}
+
+func (e *jsonEncDriver) EncodeSymbol(v string) {
+	// e.EncodeString(c_UTF8, v)
 	e.quoteStr(v)
 }
 
 func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 	// if encoding raw bytes and RawBytesExt is configured, use it to encode
-	if v == nil {
-		e.EncodeNil()
+	if c == c_RAW && e.se.i != nil {
+		e.EncodeExt(v, 0, &e.se, e.e)
 		return
 	}
-	if c == cRAW {
-		if e.se.InterfaceExt != nil {
-			e.EncodeExt(v, 0, &e.se, e.e)
-			return
-		}
-
+	if c == c_RAW {
 		slen := base64.StdEncoding.EncodedLen(len(v))
-		if cap(e.bs) >= slen+2 {
-			e.bs = e.bs[:slen+2]
+		if cap(e.bs) >= slen {
+			e.bs = e.bs[:slen]
 		} else {
-			e.bs = make([]byte, slen+2)
+			e.bs = make([]byte, slen)
 		}
-		e.bs[0] = '"'
-		base64.StdEncoding.Encode(e.bs[1:], v)
-		e.bs[slen+1] = '"'
-		e.ew.writeb(e.bs)
+		base64.StdEncoding.Encode(e.bs, v)
+		e.w.writen1('"')
+		e.w.writeb(e.bs)
+		e.w.writen1('"')
 	} else {
+		// e.EncodeString(c, string(v))
 		e.quoteStr(stringView(v))
 	}
 }
 
 func (e *jsonEncDriver) EncodeAsis(v []byte) {
-	e.ew.writeb(v)
+	e.w.writeb(v)
 }
 
 func (e *jsonEncDriver) quoteStr(s string) {
 	// adapted from std pkg encoding/json
 	const hex = "0123456789abcdef"
-	w := e.ew
-	htmlasis := e.h.HTMLCharsAsIs
+	w := e.w
 	w.writen1('"')
-	var start int
-	for i, slen := 0, len(s); i < slen; {
+	start := 0
+	for i := 0; i < len(s); {
 		// encode all bytes < 0x20 (except \r, \n).
 		// also encode < > & to prevent security holes when served to some browsers.
 		if b := s[i]; b < utf8.RuneSelf {
-			// if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
-			// if (htmlasis && jsonCharSafeSet.isset(b)) || jsonCharHtmlSafeSet.isset(b) {
-			if jsonCharHtmlSafeSet.isset(b) || (htmlasis && jsonCharSafeSet.isset(b)) {
+			if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
 				i++
 				continue
 			}
@@ -527,6 +333,13 @@ func (e *jsonEncDriver) quoteStr(s string) {
 				w.writen2('\\', 'f')
 			case '\t':
 				w.writen2('\\', 't')
+			case '<', '>', '&':
+				if e.h.HTMLCharsAsIs {
+					w.writen1(b)
+				} else {
+					w.writestr(`\u00`)
+					w.writen2(hex[b>>4], hex[b&0xF])
+				}
 			default:
 				w.writestr(`\u00`)
 				w.writen2(hex[b>>4], hex[b&0xF])
@@ -565,219 +378,267 @@ func (e *jsonEncDriver) quoteStr(s string) {
 	w.writen1('"')
 }
 
-type jsonDecDriver struct {
-	noBuiltInTypes
-	d  *Decoder
-	h  *JsonHandle
-	r  decReader // *decReaderSwitch // decReader
-	se extWrapper
-
-	// ---- writable fields during execution --- *try* to keep in sep cache line
+//--------------------------------
 
-	c containerState
-	// tok is used to store the token read right after skipWhiteSpace.
-	tok   uint8
-	fnull bool    // found null from appendStringAsBytes
-	bs    []byte  // scratch. Initialized from b. Used for parsing strings or numbers.
-	bstr  [8]byte // scratch used for string \UXXX parsing
-	// ---- cpu cache line boundary?
-	b  [jsonScratchArrayLen]byte // scratch 1, used for parsing strings or numbers or time.Time
-	b2 [jsonScratchArrayLen]byte // scratch 2, used only for readUntil, decNumBytes
-
-	_ [3]uint64 // padding
-	// n jsonNum
+type jsonNum struct {
+	// bytes            []byte // may have [+-.eE0-9]
+	mantissa         uint64 // where mantissa ends, and maybe dot begins.
+	exponent         int16  // exponent value.
+	manOverflow      bool
+	neg              bool // started with -. No initial sign in the bytes above.
+	dot              bool // has dot
+	explicitExponent bool // explicit exponent
+}
+
+func (x *jsonNum) reset() {
+	x.manOverflow = false
+	x.neg = false
+	x.dot = false
+	x.explicitExponent = false
+	x.mantissa = 0
+	x.exponent = 0
+}
+
+// uintExp is called only if exponent > 0.
+func (x *jsonNum) uintExp() (n uint64, overflow bool) {
+	n = x.mantissa
+	e := x.exponent
+	if e >= int16(len(jsonUint64Pow10)) {
+		overflow = true
+		return
+	}
+	n *= jsonUint64Pow10[e]
+	if n < x.mantissa || n > jsonNumUintMaxVal {
+		overflow = true
+		return
+	}
+	return
+	// for i := int16(0); i < e; i++ {
+	// 	if n >= jsonNumUintCutoff {
+	// 		overflow = true
+	// 		return
+	// 	}
+	// 	n *= 10
+	// }
+	// return
 }
 
-// func jsonIsWS(b byte) bool {
-// 	// return b == ' ' || b == '\t' || b == '\r' || b == '\n'
-// 	return jsonCharWhitespaceSet.isset(b)
-// }
+// these constants are only used withn floatVal.
+// They are brought out, so that floatVal can be inlined.
+const (
+	jsonUint64MantissaBits = 52
+	jsonMaxExponent        = int16(len(jsonFloat64Pow10)) - 1
+)
 
-func (d *jsonDecDriver) uncacheRead() {
-	if d.tok != 0 {
-		d.r.unreadn1()
-		d.tok = 0
+func (x *jsonNum) floatVal() (f float64, parseUsingStrConv bool) {
+	// We do not want to lose precision.
+	// Consequently, we will delegate to strconv.ParseFloat if any of the following happen:
+	//    - There are more digits than in math.MaxUint64: 18446744073709551615 (20 digits)
+	//      We expect up to 99.... (19 digits)
+	//    - The mantissa cannot fit into a 52 bits of uint64
+	//    - The exponent is beyond our scope ie beyong 22.
+	parseUsingStrConv = x.manOverflow ||
+		x.exponent > jsonMaxExponent ||
+		(x.exponent < 0 && -(x.exponent) > jsonMaxExponent) ||
+		x.mantissa>>jsonUint64MantissaBits != 0
+
+	if parseUsingStrConv {
+		return
 	}
-}
 
-func (d *jsonDecDriver) ReadMapStart() int {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	// all good. so handle parse here.
+	f = float64(x.mantissa)
+	// fmt.Printf(".Float: uint64 value: %v, float: %v\n", m, f)
+	if x.neg {
+		f = -f
 	}
-	const xc uint8 = '{'
-	if d.tok != xc {
-		d.d.errorf("read map - expect char '%c' but got char '%c'", xc, d.tok)
+	if x.exponent > 0 {
+		f *= jsonFloat64Pow10[x.exponent]
+	} else if x.exponent < 0 {
+		f /= jsonFloat64Pow10[-x.exponent]
 	}
-	d.tok = 0
-	d.c = containerMapStart
-	return -1
+	return
 }
 
-func (d *jsonDecDriver) ReadArrayStart() int {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	const xc uint8 = '['
-	if d.tok != xc {
-		d.d.errorf("read array - expect char '%c' but got char '%c'", xc, d.tok)
-	}
-	d.tok = 0
-	d.c = containerArrayStart
-	return -1
+type jsonDecDriver struct {
+	noBuiltInTypes
+	d *Decoder
+	h *JsonHandle
+	r decReader
+
+	c containerState
+	// tok is used to store the token read right after skipWhiteSpace.
+	tok uint8
+
+	bstr [8]byte  // scratch used for string \UXXX parsing
+	b    [64]byte // scratch, used for parsing strings or numbers
+	b2   [64]byte // scratch, used only for decodeBytes (after base64)
+	bs   []byte   // scratch. Initialized from b. Used for parsing strings or numbers.
+
+	se setExtWrapper
+
+	n jsonNum
 }
 
-func (d *jsonDecDriver) CheckBreak() bool {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	return d.tok == '}' || d.tok == ']'
+func jsonIsWS(b byte) bool {
+	return b == ' ' || b == '\t' || b == '\r' || b == '\n'
 }
 
-// For the ReadXXX methods below, we could just delegate to helper functions
-// readContainerState(c containerState, xc uint8, check bool)
-// - ReadArrayElem would become:
-//   readContainerState(containerArrayElem, ',', d.c != containerArrayStart)
-//
-// However, until mid-stack inlining comes in go1.11 which supports inlining of
-// one-liners, we explicitly write them all 5 out to elide the extra func call.
-//
-// TODO: For Go 1.11, if inlined, consider consolidating these.
+// // This will skip whitespace characters and return the next byte to read.
+// // The next byte determines what the value will be one of.
+// func (d *jsonDecDriver) skipWhitespace() {
+// 	// fast-path: do not enter loop. Just check first (in case no whitespace).
+// 	b := d.r.readn1()
+// 	if jsonIsWS(b) {
+// 		r := d.r
+// 		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+// 		}
+// 	}
+// 	d.tok = b
+// }
 
-func (d *jsonDecDriver) ReadArrayElem() {
-	const xc uint8 = ','
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.c != containerArrayStart {
-		if d.tok != xc {
-			d.d.errorf("read array element - expect char '%c' but got char '%c'", xc, d.tok)
-		}
+func (d *jsonDecDriver) uncacheRead() {
+	if d.tok != 0 {
+		d.r.unreadn1()
 		d.tok = 0
 	}
-	d.c = containerArrayElem
 }
 
-func (d *jsonDecDriver) ReadArrayEnd() {
-	const xc uint8 = ']'
+func (d *jsonDecDriver) sendContainerState(c containerState) {
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.tok != xc {
-		d.d.errorf("read array end - expect char '%c' but got char '%c'", xc, d.tok)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-	d.tok = 0
-	d.c = containerArrayEnd
-}
-
-func (d *jsonDecDriver) ReadMapElemKey() {
-	const xc uint8 = ','
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	var xc uint8 // char expected
+	if c == containerMapKey {
+		if d.c != containerMapStart {
+			xc = ','
+		}
+	} else if c == containerMapValue {
+		xc = ':'
+	} else if c == containerMapEnd {
+		xc = '}'
+	} else if c == containerArrayElem {
+		if d.c != containerArrayStart {
+			xc = ','
+		}
+	} else if c == containerArrayEnd {
+		xc = ']'
 	}
-	if d.c != containerMapStart {
+	if xc != 0 {
 		if d.tok != xc {
-			d.d.errorf("read map key - expect char '%c' but got char '%c'", xc, d.tok)
+			d.d.errorf("json: expect char '%c' but got char '%c'", xc, d.tok)
 		}
 		d.tok = 0
 	}
-	d.c = containerMapKey
-}
-
-func (d *jsonDecDriver) ReadMapElemValue() {
-	const xc uint8 = ':'
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.tok != xc {
-		d.d.errorf("read map value - expect char '%c' but got char '%c'", xc, d.tok)
-	}
-	d.tok = 0
-	d.c = containerMapValue
+	d.c = c
 }
 
-func (d *jsonDecDriver) ReadMapEnd() {
-	const xc uint8 = '}'
+func (d *jsonDecDriver) CheckBreak() bool {
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-	if d.tok != xc {
-		d.d.errorf("read map end - expect char '%c' but got char '%c'", xc, d.tok)
+	if d.tok == '}' || d.tok == ']' {
+		// d.tok = 0 // only checking, not consuming
+		return true
 	}
-	d.tok = 0
-	d.c = containerMapEnd
+	return false
 }
 
-func (d *jsonDecDriver) readLit(length, fromIdx uint8) {
-	bs := d.r.readx(int(length))
+func (d *jsonDecDriver) readStrIdx(fromIdx, toIdx uint8) {
+	bs := d.r.readx(int(toIdx - fromIdx))
 	d.tok = 0
-	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiterals[fromIdx:fromIdx+length]) {
-		d.d.errorf("expecting %s: got %s", jsonLiterals[fromIdx:fromIdx+length], bs)
-		return
+	if jsonValidateSymbols {
+		if !bytes.Equal(bs, jsonLiterals[fromIdx:toIdx]) {
+			d.d.errorf("json: expecting %s: got %s", jsonLiterals[fromIdx:toIdx], bs)
+			return
+		}
 	}
 }
 
 func (d *jsonDecDriver) TryDecodeAsNil() bool {
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-	// we shouldn't try to see if "null" was here, right?
-	// only the plain string: `null` denotes a nil (ie not quotes)
 	if d.tok == 'n' {
-		d.readLit(3, jsonLitNull+1) // (n)ull
+		d.readStrIdx(10, 13) // ull
 		return true
 	}
 	return false
 }
 
-func (d *jsonDecDriver) DecodeBool() (v bool) {
+func (d *jsonDecDriver) DecodeBool() bool {
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-	fquot := d.c == containerMapKey && d.tok == '"'
-	if fquot {
-		d.tok = d.r.readn1()
+	if d.tok == 'f' {
+		d.readStrIdx(5, 9) // alse
+		return false
 	}
-	switch d.tok {
-	case 'f':
-		d.readLit(4, jsonLitFalse+1) // (f)alse
-		// v = false
-	case 't':
-		d.readLit(3, jsonLitTrue+1) // (t)rue
-		v = true
-	default:
-		d.d.errorf("decode bool: got first char %c", d.tok)
-		// v = false // "unreachable"
+	if d.tok == 't' {
+		d.readStrIdx(1, 4) // rue
+		return true
+	}
+	d.d.errorf("json: decode bool: got first char %c", d.tok)
+	return false // "unreachable"
+}
+
+func (d *jsonDecDriver) ReadMapStart() int {
+	if d.tok == 0 {
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-	if fquot {
-		d.r.readn1()
+	if d.tok != '{' {
+		d.d.errorf("json: expect char '%c' but got char '%c'", '{', d.tok)
 	}
-	return
+	d.tok = 0
+	d.c = containerMapStart
+	return -1
 }
 
-func (d *jsonDecDriver) DecodeTime() (t time.Time) {
-	// read string, and pass the string into json.unmarshal
-	d.appendStringAsBytes()
-	if d.fnull {
-		return
+func (d *jsonDecDriver) ReadArrayStart() int {
+	if d.tok == 0 {
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-	t, err := time.Parse(time.RFC3339, stringView(d.bs))
-	if err != nil {
-		d.d.errorv(err)
+	if d.tok != '[' {
+		d.d.errorf("json: expect char '%c' but got char '%c'", '[', d.tok)
 	}
-	return
+	d.tok = 0
+	d.c = containerArrayStart
+	return -1
 }
 
 func (d *jsonDecDriver) ContainerType() (vt valueType) {
 	// check container type by checking the first char
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-
-	// optimize this, so we don't do 4 checks but do one computation.
-	// return jsonContainerSet[d.tok]
-
-	// ContainerType is mostly called for Map and Array,
-	// so this conditional is good enough (max 2 checks typically)
 	if b := d.tok; b == '{' {
 		return valueTypeMap
 	} else if b == '[' {
@@ -788,87 +649,265 @@ func (d *jsonDecDriver) ContainerType() (vt valueType) {
 		return valueTypeString
 	}
 	return valueTypeUnset
+	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
+	// return false // "unreachable"
 }
 
-func (d *jsonDecDriver) decNumBytes() (bs []byte) {
-	// stores num bytes in d.bs
+func (d *jsonDecDriver) decNum(storeBytes bool) {
+	// If it is has a . or an e|E, decode as a float; else decode as an int.
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
-	if d.tok == '"' {
-		bs = d.r.readUntil(d.b2[:0], '"')
-		bs = bs[:len(bs)-1]
-	} else {
-		d.r.unreadn1()
-		bs = d.r.readTo(d.bs[:0], &jsonNumSet)
+	b := d.tok
+	var str bool
+	if b == '"' {
+		str = true
+		b = d.r.readn1()
+	}
+	if !(b == '+' || b == '-' || b == '.' || (b >= '0' && b <= '9')) {
+		d.d.errorf("json: decNum: got first char '%c'", b)
+		return
 	}
 	d.tok = 0
-	return bs
-}
 
-func (d *jsonDecDriver) DecodeUint64() (u uint64) {
-	bs := d.decNumBytes()
-	n, neg, badsyntax, overflow := jsonParseInteger(bs)
-	if overflow {
-		d.d.errorf("overflow parsing unsigned integer: %s", bs)
-	} else if neg {
-		d.d.errorf("minus found parsing unsigned integer: %s", bs)
-	} else if badsyntax {
-		// fallback: try to decode as float, and cast
-		n = d.decUint64ViaFloat(stringView(bs))
-	}
-	return n
-}
+	const cutoff = (1<<64-1)/uint64(10) + 1 // cutoff64(base)
+	const jsonNumUintMaxVal = 1<<uint64(64) - 1
+
+	n := &d.n
+	r := d.r
+	n.reset()
+	d.bs = d.bs[:0]
+
+	if str && storeBytes {
+		d.bs = append(d.bs, '"')
+	}
+
+	// The format of a number is as below:
+	// parsing:     sign? digit* dot? digit* e?  sign? digit*
+	// states:  0   1*    2      3*   4      5*  6     7
+	// We honor this state so we can break correctly.
+	var state uint8 = 0
+	var eNeg bool
+	var e int16
+	var eof bool
+LOOP:
+	for !eof {
+		// fmt.Printf("LOOP: b: %q\n", b)
+		switch b {
+		case '+':
+			switch state {
+			case 0:
+				state = 2
+				// do not add sign to the slice ...
+				b, eof = r.readn1eof()
+				continue
+			case 6: // typ = jsonNumFloat
+				state = 7
+			default:
+				break LOOP
+			}
+		case '-':
+			switch state {
+			case 0:
+				state = 2
+				n.neg = true
+				// do not add sign to the slice ...
+				b, eof = r.readn1eof()
+				continue
+			case 6: // typ = jsonNumFloat
+				eNeg = true
+				state = 7
+			default:
+				break LOOP
+			}
+		case '.':
+			switch state {
+			case 0, 2: // typ = jsonNumFloat
+				state = 4
+				n.dot = true
+			default:
+				break LOOP
+			}
+		case 'e', 'E':
+			switch state {
+			case 0, 2, 4: // typ = jsonNumFloat
+				state = 6
+				// n.mantissaEndIndex = int16(len(n.bytes))
+				n.explicitExponent = true
+			default:
+				break LOOP
+			}
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			switch state {
+			case 0:
+				state = 2
+				fallthrough
+			case 2:
+				fallthrough
+			case 4:
+				if n.dot {
+					n.exponent--
+				}
+				if n.mantissa >= jsonNumUintCutoff {
+					n.manOverflow = true
+					break
+				}
+				v := uint64(b - '0')
+				n.mantissa *= 10
+				if v != 0 {
+					n1 := n.mantissa + v
+					if n1 < n.mantissa || n1 > jsonNumUintMaxVal {
+						n.manOverflow = true // n+v overflows
+						break
+					}
+					n.mantissa = n1
+				}
+			case 6:
+				state = 7
+				fallthrough
+			case 7:
+				if !(b == '0' && e == 0) {
+					e = e*10 + int16(b-'0')
+				}
+			default:
+				break LOOP
+			}
+		case '"':
+			if str {
+				if storeBytes {
+					d.bs = append(d.bs, '"')
+				}
+				b, eof = r.readn1eof()
+			}
+			break LOOP
+		default:
+			break LOOP
+		}
+		if storeBytes {
+			d.bs = append(d.bs, b)
+		}
+		b, eof = r.readn1eof()
+	}
 
-func (d *jsonDecDriver) DecodeInt64() (i int64) {
-	const cutoff = uint64(1 << uint(64-1))
-	bs := d.decNumBytes()
-	n, neg, badsyntax, overflow := jsonParseInteger(bs)
-	if overflow {
-		d.d.errorf("overflow parsing integer: %s", bs)
-	} else if badsyntax {
-		// d.d.errorf("invalid syntax for integer: %s", bs)
-		// fallback: try to decode as float, and cast
-		if neg {
-			n = d.decUint64ViaFloat(stringView(bs[1:]))
+	if jsonTruncateMantissa && n.mantissa != 0 {
+		for n.mantissa%10 == 0 {
+			n.mantissa /= 10
+			n.exponent++
+		}
+	}
+
+	if e != 0 {
+		if eNeg {
+			n.exponent -= e
 		} else {
-			n = d.decUint64ViaFloat(stringView(bs))
+			n.exponent += e
 		}
 	}
-	if neg {
-		if n > cutoff {
-			d.d.errorf("overflow parsing integer: %s", bs)
+
+	// d.n = n
+
+	if !eof {
+		if jsonUnreadAfterDecNum {
+			r.unreadn1()
+		} else {
+			if !jsonIsWS(b) {
+				d.tok = b
+			}
 		}
-		i = -(int64(n))
-	} else {
-		if n >= cutoff {
-			d.d.errorf("overflow parsing integer: %s", bs)
+	}
+	// fmt.Printf("1: n: bytes: %s, neg: %v, dot: %v, exponent: %v, mantissaEndIndex: %v\n",
+	// 	n.bytes, n.neg, n.dot, n.exponent, n.mantissaEndIndex)
+	return
+}
+
+func (d *jsonDecDriver) DecodeInt(bitsize uint8) (i int64) {
+	d.decNum(false)
+	n := &d.n
+	if n.manOverflow {
+		d.d.errorf("json: overflow integer after: %v", n.mantissa)
+		return
+	}
+	var u uint64
+	if n.exponent == 0 {
+		u = n.mantissa
+	} else if n.exponent < 0 {
+		d.d.errorf("json: fractional integer")
+		return
+	} else if n.exponent > 0 {
+		var overflow bool
+		if u, overflow = n.uintExp(); overflow {
+			d.d.errorf("json: overflow integer")
+			return
 		}
-		i = int64(n)
 	}
+	i = int64(u)
+	if n.neg {
+		i = -i
+	}
+	if chkOvf.Int(i, bitsize) {
+		d.d.errorf("json: overflow %v bits: %s", bitsize, d.bs)
+		return
+	}
+	// fmt.Printf("DecodeInt: %v\n", i)
 	return
 }
 
-func (d *jsonDecDriver) decUint64ViaFloat(s string) (u uint64) {
-	f, err := strconv.ParseFloat(s, 64)
-	if err != nil {
-		d.d.errorf("invalid syntax for integer: %s", s)
-		// d.d.errorv(err)
+// floatVal MUST only be called after a decNum, as d.bs now contains the bytes of the number
+func (d *jsonDecDriver) floatVal() (f float64) {
+	f, useStrConv := d.n.floatVal()
+	if useStrConv {
+		var err error
+		if f, err = strconv.ParseFloat(stringView(d.bs), 64); err != nil {
+			panic(fmt.Errorf("parse float: %s, %v", d.bs, err))
+		}
+		if d.n.neg {
+			f = -f
+		}
 	}
-	fi, ff := math.Modf(f)
-	if ff > 0 {
-		d.d.errorf("fractional part found parsing integer: %s", s)
-	} else if fi > float64(math.MaxUint64) {
-		d.d.errorf("overflow parsing integer: %s", s)
+	return
+}
+
+func (d *jsonDecDriver) DecodeUint(bitsize uint8) (u uint64) {
+	d.decNum(false)
+	n := &d.n
+	if n.neg {
+		d.d.errorf("json: unsigned integer cannot be negative")
+		return
 	}
-	return uint64(fi)
+	if n.manOverflow {
+		d.d.errorf("json: overflow integer after: %v", n.mantissa)
+		return
+	}
+	if n.exponent == 0 {
+		u = n.mantissa
+	} else if n.exponent < 0 {
+		d.d.errorf("json: fractional integer")
+		return
+	} else if n.exponent > 0 {
+		var overflow bool
+		if u, overflow = n.uintExp(); overflow {
+			d.d.errorf("json: overflow integer")
+			return
+		}
+	}
+	if chkOvf.Uint(u, bitsize) {
+		d.d.errorf("json: overflow %v bits: %s", bitsize, d.bs)
+		return
+	}
+	// fmt.Printf("DecodeUint: %v\n", u)
+	return
 }
 
-func (d *jsonDecDriver) DecodeFloat64() (f float64) {
-	bs := d.decNumBytes()
-	f, err := strconv.ParseFloat(stringView(bs), 64)
-	if err != nil {
-		d.d.errorv(err)
+func (d *jsonDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
+	d.decNum(true)
+	f = d.floatVal()
+	if chkOverflow32 && chkOvf.Float32(f) {
+		d.d.errorf("json: overflow float32: %v, %s", f, d.bs)
+		return
 	}
 	return
 }
@@ -886,31 +925,23 @@ func (d *jsonDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxta
 	return
 }
 
-func (d *jsonDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+func (d *jsonDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) {
 	// if decoding into raw bytes, and the RawBytesExt is configured, use it to decode.
-	if d.se.InterfaceExt != nil {
+	if !isstring && d.se.i != nil {
 		bsOut = bs
 		d.DecodeExt(&bsOut, 0, &d.se)
 		return
 	}
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.tok == '[' {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
 	d.appendStringAsBytes()
-	// base64 encodes []byte{} as "", and we encode nil []byte as null.
-	// Consequently, base64 should decode null as a nil []byte, and "" as an empty []byte{}.
-	// appendStringAsBytes returns a zero-len slice for both, so as not to reset d.bs.
-	// However, it sets a fnull field to true, so we can check if a null was found.
+	// if isstring, then just return the bytes, even if it is using the scratch buffer.
+	// the bytes will be converted to a string as needed.
+	if isstring {
+		return d.bs
+	}
+	// if appendStringAsBytes returned a zero-len slice, then treat as nil.
+	// This should only happen for null, and "".
 	if len(d.bs) == 0 {
-		if d.fnull {
-			return nil
-		}
-		return []byte{}
+		return nil
 	}
 	bs0 := d.bs
 	slen := base64.StdEncoding.DecodedLen(len(bs0))
@@ -923,7 +954,7 @@ func (d *jsonDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 	}
 	slen2, err := base64.StdEncoding.Decode(bsOut, bs0)
 	if err != nil {
-		d.d.errorf("error decoding base64 binary '%s': %v", bs0, err)
+		d.d.errorf("json: error decoding base64 binary '%s': %v", bs0, err)
 		return nil
 	}
 	if slen != slen2 {
@@ -934,256 +965,172 @@ func (d *jsonDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 
 func (d *jsonDecDriver) DecodeString() (s string) {
 	d.appendStringAsBytes()
-	return d.bsToString()
-}
-
-func (d *jsonDecDriver) DecodeStringAsBytes() (s []byte) {
-	d.appendStringAsBytes()
-	return d.bs
+	// if x := d.s.sc; x != nil && x.so && x.st == '}' { // map key
+	if d.c == containerMapKey {
+		return d.d.string(d.bs)
+	}
+	return string(d.bs)
 }
 
 func (d *jsonDecDriver) appendStringAsBytes() {
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
 
-	d.fnull = false
-	if d.tok != '"' {
-		// d.d.errorf("expect char '%c' but got char '%c'", '"', d.tok)
-		// handle non-string scalar: null, true, false or a number
-		switch d.tok {
-		case 'n':
-			d.readLit(3, jsonLitNull+1) // (n)ull
-			d.bs = d.bs[:0]
-			d.fnull = true
-		case 'f':
-			d.readLit(4, jsonLitFalse+1) // (f)alse
-			d.bs = d.bs[:5]
-			copy(d.bs, "false")
-		case 't':
-			d.readLit(3, jsonLitTrue+1) // (t)rue
-			d.bs = d.bs[:4]
-			copy(d.bs, "true")
-		default:
-			// try to parse a valid number
-			bs := d.decNumBytes()
-			if len(bs) <= cap(d.bs) {
-				d.bs = d.bs[:len(bs)]
-			} else {
-				d.bs = make([]byte, len(bs))
-			}
-			copy(d.bs, bs)
-		}
+	// handle null as a string
+	if d.tok == 'n' {
+		d.readStrIdx(10, 13) // ull
+		d.bs = d.bs[:0]
 		return
 	}
 
+	if d.tok != '"' {
+		d.d.errorf("json: expect char '%c' but got char '%c'", '"', d.tok)
+	}
 	d.tok = 0
-	r := d.r
-	var cs = r.readUntil(d.b2[:0], '"')
-	var cslen = len(cs)
-	var c uint8
+
 	v := d.bs[:0]
-	// append on each byte seen can be expensive, so we just
-	// keep track of where we last read a contiguous set of
-	// non-special bytes (using cursor variable),
-	// and when we see a special byte
-	// e.g. end-of-slice, " or \,
-	// we will append the full range into the v slice before proceeding
-	for i, cursor := 0, 0; ; {
-		if i == cslen {
-			v = append(v, cs[cursor:]...)
-			cs = r.readUntil(d.b2[:0], '"')
-			cslen = len(cs)
-			i, cursor = 0, 0
-		}
-		c = cs[i]
+	var c uint8
+	r := d.r
+	for {
+		c = r.readn1()
 		if c == '"' {
-			v = append(v, cs[cursor:i]...)
 			break
-		}
-		if c != '\\' {
-			i++
-			continue
-		}
-		v = append(v, cs[cursor:i]...)
-		i++
-		c = cs[i]
-		switch c {
-		case '"', '\\', '/', '\'':
-			v = append(v, c)
-		case 'b':
-			v = append(v, '\b')
-		case 'f':
-			v = append(v, '\f')
-		case 'n':
-			v = append(v, '\n')
-		case 'r':
-			v = append(v, '\r')
-		case 't':
-			v = append(v, '\t')
-		case 'u':
-			var r rune
-			var rr uint32
-			if len(cs) < i+4 { // may help reduce bounds-checking
-				d.d.errorf("need at least 4 more bytes for unicode sequence")
-			}
-			// c = cs[i+4] // may help reduce bounds-checking
-			for j := 1; j < 5; j++ {
-				// best to use explicit if-else
-				// - not a table, etc which involve memory loads, array lookup with bounds checks, etc
-				c = cs[i+j]
-				if c >= '0' && c <= '9' {
-					rr = rr*16 + uint32(c-jsonU4Chk2)
-				} else if c >= 'a' && c <= 'f' {
-					rr = rr*16 + uint32(c-jsonU4Chk1)
-				} else if c >= 'A' && c <= 'F' {
-					rr = rr*16 + uint32(c-jsonU4Chk0)
-				} else {
-					r = unicode.ReplacementChar
-					i += 4
-					goto encode_rune
-				}
-			}
-			r = rune(rr)
-			i += 4
-			if utf16.IsSurrogate(r) {
-				if len(cs) >= i+6 && cs[i+2] == 'u' && cs[i+1] == '\\' {
-					i += 2
-					// c = cs[i+4] // may help reduce bounds-checking
-					var rr1 uint32
-					for j := 1; j < 5; j++ {
-						c = cs[i+j]
-						if c >= '0' && c <= '9' {
-							rr = rr*16 + uint32(c-jsonU4Chk2)
-						} else if c >= 'a' && c <= 'f' {
-							rr = rr*16 + uint32(c-jsonU4Chk1)
-						} else if c >= 'A' && c <= 'F' {
-							rr = rr*16 + uint32(c-jsonU4Chk0)
-						} else {
-							r = unicode.ReplacementChar
-							i += 4
-							goto encode_rune
-						}
-					}
-					r = utf16.DecodeRune(r, rune(rr1))
-					i += 4
-				} else {
-					r = unicode.ReplacementChar
-					goto encode_rune
+		} else if c == '\\' {
+			c = r.readn1()
+			switch c {
+			case '"', '\\', '/', '\'':
+				v = append(v, c)
+			case 'b':
+				v = append(v, '\b')
+			case 'f':
+				v = append(v, '\f')
+			case 'n':
+				v = append(v, '\n')
+			case 'r':
+				v = append(v, '\r')
+			case 't':
+				v = append(v, '\t')
+			case 'u':
+				rr := d.jsonU4(false)
+				// fmt.Printf("$$$$$$$$$: is surrogate: %v\n", utf16.IsSurrogate(rr))
+				if utf16.IsSurrogate(rr) {
+					rr = utf16.DecodeRune(rr, d.jsonU4(true))
 				}
+				w2 := utf8.EncodeRune(d.bstr[:], rr)
+				v = append(v, d.bstr[:w2]...)
+			default:
+				d.d.errorf("json: unsupported escaped value: %c", c)
 			}
-		encode_rune:
-			w2 := utf8.EncodeRune(d.bstr[:], r)
-			v = append(v, d.bstr[:w2]...)
-		default:
-			d.d.errorf("unsupported escaped value: %c", c)
+		} else {
+			v = append(v, c)
 		}
-		i++
-		cursor = i
 	}
 	d.bs = v
 }
 
-func (d *jsonDecDriver) nakedNum(z *decNaked, bs []byte) (err error) {
-	const cutoff = uint64(1 << uint(64-1))
-	var n uint64
-	var neg, badsyntax, overflow bool
-
-	if d.h.PreferFloat {
-		goto F
-	}
-	n, neg, badsyntax, overflow = jsonParseInteger(bs)
-	if badsyntax || overflow {
-		goto F
-	}
-	if neg {
-		if n > cutoff {
-			goto F
-		}
-		z.v = valueTypeInt
-		z.i = -(int64(n))
-	} else if d.h.SignedInteger {
-		if n >= cutoff {
-			goto F
+func (d *jsonDecDriver) jsonU4(checkSlashU bool) rune {
+	r := d.r
+	if checkSlashU && !(r.readn1() == '\\' && r.readn1() == 'u') {
+		d.d.errorf(`json: unquoteStr: invalid unicode sequence. Expecting \u`)
+		return 0
+	}
+	// u, _ := strconv.ParseUint(string(d.bstr[:4]), 16, 64)
+	var u uint32
+	for i := 0; i < 4; i++ {
+		v := r.readn1()
+		if '0' <= v && v <= '9' {
+			v = v - '0'
+		} else if 'a' <= v && v <= 'z' {
+			v = v - 'a' + 10
+		} else if 'A' <= v && v <= 'Z' {
+			v = v - 'A' + 10
+		} else {
+			d.d.errorf(`json: unquoteStr: invalid hex char in \u unicode sequence: %q`, v)
+			return 0
 		}
-		z.v = valueTypeInt
-		z.i = int64(n)
-	} else {
-		z.v = valueTypeUint
-		z.u = n
+		u = u*16 + uint32(v)
 	}
-	return
-F:
-	z.v = valueTypeFloat
-	z.f, err = strconv.ParseFloat(stringView(bs), 64)
-	return
-}
-
-func (d *jsonDecDriver) bsToString() string {
-	// if x := d.s.sc; x != nil && x.so && x.st == '}' { // map key
-	if jsonAlwaysReturnInternString || d.c == containerMapKey {
-		return d.d.string(d.bs)
-	}
-	return string(d.bs)
+	return rune(u)
 }
 
 func (d *jsonDecDriver) DecodeNaked() {
-	z := d.d.n
+	z := &d.d.n
 	// var decodeFurther bool
 
 	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+		var b byte
+		r := d.r
+		for b = r.readn1(); jsonIsWS(b); b = r.readn1() {
+		}
+		d.tok = b
 	}
 	switch d.tok {
 	case 'n':
-		d.readLit(3, jsonLitNull+1) // (n)ull
+		d.readStrIdx(10, 13) // ull
 		z.v = valueTypeNil
 	case 'f':
-		d.readLit(4, jsonLitFalse+1) // (f)alse
+		d.readStrIdx(5, 9) // alse
 		z.v = valueTypeBool
 		z.b = false
 	case 't':
-		d.readLit(3, jsonLitTrue+1) // (t)rue
+		d.readStrIdx(1, 4) // rue
 		z.v = valueTypeBool
 		z.b = true
 	case '{':
-		z.v = valueTypeMap // don't consume. kInterfaceNaked will call ReadMapStart
+		z.v = valueTypeMap
+		// d.tok = 0 // don't consume. kInterfaceNaked will call ReadMapStart
+		// decodeFurther = true
 	case '[':
-		z.v = valueTypeArray // don't consume. kInterfaceNaked will call ReadArrayStart
+		z.v = valueTypeArray
+		// d.tok = 0 // don't consume. kInterfaceNaked will call ReadArrayStart
+		// decodeFurther = true
 	case '"':
-		// if a string, and MapKeyAsString, then try to decode it as a nil, bool or number first
-		d.appendStringAsBytes()
-		if len(d.bs) > 0 && d.c == containerMapKey && d.h.MapKeyAsString {
-			switch stringView(d.bs) {
-			case "null":
-				z.v = valueTypeNil
-			case "true":
-				z.v = valueTypeBool
-				z.b = true
-			case "false":
-				z.v = valueTypeBool
-				z.b = false
+		z.v = valueTypeString
+		z.s = d.DecodeString()
+	default: // number
+		d.decNum(true)
+		n := &d.n
+		// if the string had a any of [.eE], then decode as float.
+		switch {
+		case n.explicitExponent, n.dot, n.exponent < 0, n.manOverflow:
+			z.v = valueTypeFloat
+			z.f = d.floatVal()
+		case n.exponent == 0:
+			u := n.mantissa
+			switch {
+			case n.neg:
+				z.v = valueTypeInt
+				z.i = -int64(u)
+			case d.h.SignedInteger:
+				z.v = valueTypeInt
+				z.i = int64(u)
 			default:
-				// check if a number: float, int or uint
-				if err := d.nakedNum(z, d.bs); err != nil {
-					z.v = valueTypeString
-					z.s = d.bsToString()
-				}
+				z.v = valueTypeUint
+				z.u = u
+			}
+		default:
+			u, overflow := n.uintExp()
+			switch {
+			case overflow:
+				z.v = valueTypeFloat
+				z.f = d.floatVal()
+			case n.neg:
+				z.v = valueTypeInt
+				z.i = -int64(u)
+			case d.h.SignedInteger:
+				z.v = valueTypeInt
+				z.i = int64(u)
+			default:
+				z.v = valueTypeUint
+				z.u = u
 			}
-		} else {
-			z.v = valueTypeString
-			z.s = d.bsToString()
-		}
-	default: // number
-		bs := d.decNumBytes()
-		if len(bs) == 0 {
-			d.d.errorf("decode number from empty string")
-			return
-		}
-		if err := d.nakedNum(z, bs); err != nil {
-			d.d.errorf("decode number from %s: %v", bs, err)
-			return
 		}
+		// fmt.Printf("DecodeNaked: Number: %T, %v\n", v, v)
 	}
 	// if decodeFurther {
 	// 	d.s.sc.retryRead()
@@ -1197,26 +1144,24 @@ func (d *jsonDecDriver) DecodeNaked() {
 //
 // Json is comprehensively supported:
 //    - decodes numbers into interface{} as int, uint or float64
-//      based on how the number looks and some config parameters e.g. PreferFloat, SignedInt, etc.
-//    - decode integers from float formatted numbers e.g. 1.27e+8
-//    - decode any json value (numbers, bool, etc) from quoted strings
 //    - configurable way to encode/decode []byte .
 //      by default, encodes and decodes []byte using base64 Std Encoding
 //    - UTF-8 support for encoding and decoding
 //
 // It has better performance than the json library in the standard library,
-// by leveraging the performance improvements of the codec library.
+// by leveraging the performance improvements of the codec library and
+// minimizing allocations.
 //
 // In addition, it doesn't read more bytes than necessary during a decode, which allows
 // reading multiple values from a stream containing json and non-json content.
 // For example, a user can read a json value, then a cbor value, then a msgpack value,
 // all from the same stream in sequence.
-//
-// Note that, when decoding quoted strings, invalid UTF-8 or invalid UTF-16 surrogate pairs are
-// not treated as an error. Instead, they are replaced by the Unicode replacement character U+FFFD.
 type JsonHandle struct {
 	textEncodingType
 	BasicHandle
+	// RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way.
+	// If not configured, raw bytes are encoded to/from base64 text.
+	RawBytesExt InterfaceExt
 
 	// Indent indicates how a value is encoded.
 	//   - If positive, indent by that number of spaces.
@@ -1234,190 +1179,69 @@ type JsonHandle struct {
 	//   - if 'A', then encode all integers as a json string
 	//             containing the exact integer representation as a decimal.
 	//   - else    encode all integers as a json number (default)
-	IntegerAsString byte
+	IntegerAsString uint8
 
 	// HTMLCharsAsIs controls how to encode some special characters to html: < > &
 	//
 	// By default, we encode them as \uXXX
 	// to prevent security holes when served from some browsers.
 	HTMLCharsAsIs bool
-
-	// PreferFloat says that we will default to decoding a number as a float.
-	// If not set, we will examine the characters of the number and decode as an
-	// integer type if it doesn't have any of the characters [.eE].
-	PreferFloat bool
-
-	// TermWhitespace says that we add a whitespace character
-	// at the end of an encoding.
-	//
-	// The whitespace is important, especially if using numbers in a context
-	// where multiple items are written to a stream.
-	TermWhitespace bool
-
-	// MapKeyAsString says to encode all map keys as strings.
-	//
-	// Use this to enforce strict json output.
-	// The only caveat is that nil value is ALWAYS written as null (never as "null")
-	MapKeyAsString bool
-
-	// _ [2]byte // padding
-
-	// Note: below, we store hardly-used items e.g. RawBytesExt is cached in the (en|de)cDriver.
-
-	// RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way.
-	// If not configured, raw bytes are encoded to/from base64 text.
-	RawBytesExt InterfaceExt
-
-	_ [2]uint64 // padding
-}
-
-// Name returns the name of the handle: json
-func (h *JsonHandle) Name() string            { return "json" }
-func (h *JsonHandle) hasElemSeparators() bool { return true }
-func (h *JsonHandle) typical() bool {
-	return h.Indent == 0 && !h.MapKeyAsString && h.IntegerAsString != 'A' && h.IntegerAsString != 'L'
-}
-
-type jsonTypical interface {
-	typical()
 }
 
-func (h *JsonHandle) recreateEncDriver(ed encDriver) (v bool) {
-	_, v = ed.(jsonTypical)
-	return v != h.typical()
-}
-
-// SetInterfaceExt sets an extension
 func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
-}
-
-type jsonEncDriverTypicalImpl struct {
-	jsonEncDriver
-	jsonEncDriverTypical
-	_ [1]uint64 // padding
+	return h.SetExt(rt, tag, &setExtWrapper{i: ext})
 }
 
-func (x *jsonEncDriverTypicalImpl) reset() {
-	x.jsonEncDriver.reset()
-	x.jsonEncDriverTypical.reset(&x.jsonEncDriver)
-}
-
-type jsonEncDriverGenericImpl struct {
-	jsonEncDriver
-	jsonEncDriverGeneric
-}
+func (h *JsonHandle) newEncDriver(e *Encoder) encDriver {
+	hd := jsonEncDriver{e: e, h: h}
+	hd.bs = hd.b[:0]
 
-func (x *jsonEncDriverGenericImpl) reset() {
-	x.jsonEncDriver.reset()
-	x.jsonEncDriverGeneric.reset(&x.jsonEncDriver)
-}
+	hd.reset()
 
-func (h *JsonHandle) newEncDriver(e *Encoder) (ee encDriver) {
-	var hd *jsonEncDriver
-	if h.typical() {
-		var v jsonEncDriverTypicalImpl
-		ee = &v
-		hd = &v.jsonEncDriver
-	} else {
-		var v jsonEncDriverGenericImpl
-		ee = &v
-		hd = &v.jsonEncDriver
-	}
-	hd.e, hd.h, hd.bs = e, h, hd.b[:0]
-	hd.se.BytesExt = bytesExtFailer{}
-	ee.reset()
-	return
+	return &hd
 }
 
 func (h *JsonHandle) newDecDriver(d *Decoder) decDriver {
 	// d := jsonDecDriver{r: r.(*bytesDecReader), h: h}
 	hd := jsonDecDriver{d: d, h: h}
-	hd.se.BytesExt = bytesExtFailer{}
 	hd.bs = hd.b[:0]
 	hd.reset()
 	return &hd
 }
 
 func (e *jsonEncDriver) reset() {
-	e.ew = e.e.w // e.e.w // &e.e.encWriterSwitch
-	e.se.InterfaceExt = e.h.RawBytesExt
+	e.w = e.e.w
+	e.se.i = e.h.RawBytesExt
 	if e.bs != nil {
 		e.bs = e.bs[:0]
 	}
+	e.d, e.dt, e.dl, e.ds = false, false, 0, ""
+	e.c = 0
+	if e.h.Indent > 0 {
+		e.d = true
+		e.ds = jsonSpaces[:e.h.Indent]
+	} else if e.h.Indent < 0 {
+		e.d = true
+		e.dt = true
+		e.ds = jsonTabs[:-(e.h.Indent)]
+	}
 }
 
 func (d *jsonDecDriver) reset() {
-	d.r = d.d.r // &d.d.decReaderSwitch // d.d.r
-	d.se.InterfaceExt = d.h.RawBytesExt
+	d.r = d.d.r
+	d.se.i = d.h.RawBytesExt
 	if d.bs != nil {
 		d.bs = d.bs[:0]
 	}
 	d.c, d.tok = 0, 0
-	// d.n.reset()
-}
-
-func jsonFloatStrconvFmtPrec(f float64) (fmt byte, prec int) {
-	prec = -1
-	var abs = math.Abs(f)
-	if abs != 0 && (abs < 1e-6 || abs >= 1e21) {
-		fmt = 'e'
-	} else {
-		fmt = 'f'
-		// set prec to 1 iff mod is 0.
-		//     better than using jsonIsFloatBytesB2 to check if a . or E in the float bytes.
-		// this ensures that every float has an e or .0 in it.
-		if abs <= 1 {
-			if abs == 0 || abs == 1 {
-				prec = 1
-			}
-		} else if _, mod := math.Modf(abs); mod == 0 {
-			prec = 1
-		}
-	}
-	return
+	d.n.reset()
 }
 
-// custom-fitted version of strconv.Parse(Ui|I)nt.
-// Also ensures we don't have to search for .eE to determine if a float or not.
-func jsonParseInteger(s []byte) (n uint64, neg, badSyntax, overflow bool) {
-	const maxUint64 = (1<<64 - 1)
-	const cutoff = maxUint64/10 + 1
+var jsonEncodeTerminate = []byte{' '}
 
-	if len(s) == 0 {
-		badSyntax = true
-		return
-	}
-	switch s[0] {
-	case '+':
-		s = s[1:]
-	case '-':
-		s = s[1:]
-		neg = true
-	}
-	for _, c := range s {
-		if c < '0' || c > '9' {
-			badSyntax = true
-			return
-		}
-		// unsigned integers don't overflow well on multiplication, so check cutoff here
-		// e.g. (maxUint64-5)*10 doesn't overflow well ...
-		if n >= cutoff {
-			overflow = true
-			return
-		}
-		n *= 10
-		n1 := n + uint64(c-'0')
-		if n1 < n || n1 > maxUint64 {
-			overflow = true
-			return
-		}
-		n = n1
-	}
-	return
+func (h *JsonHandle) rpcEncodeTerminate() []byte {
+	return jsonEncodeTerminate
 }
 
 var _ decDriver = (*jsonDecDriver)(nil)
-var _ encDriver = (*jsonEncDriverGenericImpl)(nil)
-var _ encDriver = (*jsonEncDriverTypicalImpl)(nil)
-var _ jsonTypical = (*jsonEncDriverTypical)(nil)
+var _ encDriver = (*jsonEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/msgpack.go b/vendor/github.com/ugorji/go/codec/msgpack.go
index 3271579a1..e09d5a04a 100644
--- a/vendor/github.com/ugorji/go/codec/msgpack.go
+++ b/vendor/github.com/ugorji/go/codec/msgpack.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 /*
@@ -15,8 +15,8 @@ For compatibility with behaviour of msgpack-c reference implementation:
   - Go intX (<0)
        IS ENCODED AS
     msgpack -ve fixnum, signed
-*/
 
+*/
 package codec
 
 import (
@@ -25,7 +25,6 @@ import (
 	"math"
 	"net/rpc"
 	"reflect"
-	"time"
 )
 
 const (
@@ -79,89 +78,6 @@ const (
 	mpNegFixNumMax = 0xff
 )
 
-var mpTimeExtTag int8 = -1
-var mpTimeExtTagU = uint8(mpTimeExtTag)
-
-// var mpdesc = map[byte]string{
-// 	mpPosFixNumMin: "PosFixNumMin",
-// 	mpPosFixNumMax: "PosFixNumMax",
-// 	mpFixMapMin:    "FixMapMin",
-// 	mpFixMapMax:    "FixMapMax",
-// 	mpFixArrayMin:  "FixArrayMin",
-// 	mpFixArrayMax:  "FixArrayMax",
-// 	mpFixStrMin:    "FixStrMin",
-// 	mpFixStrMax:    "FixStrMax",
-// 	mpNil:          "Nil",
-// 	mpFalse:        "False",
-// 	mpTrue:         "True",
-// 	mpFloat:        "Float",
-// 	mpDouble:       "Double",
-// 	mpUint8:        "Uint8",
-// 	mpUint16:       "Uint16",
-// 	mpUint32:       "Uint32",
-// 	mpUint64:       "Uint64",
-// 	mpInt8:         "Int8",
-// 	mpInt16:        "Int16",
-// 	mpInt32:        "Int32",
-// 	mpInt64:        "Int64",
-// 	mpBin8:         "Bin8",
-// 	mpBin16:        "Bin16",
-// 	mpBin32:        "Bin32",
-// 	mpExt8:         "Ext8",
-// 	mpExt16:        "Ext16",
-// 	mpExt32:        "Ext32",
-// 	mpFixExt1:      "FixExt1",
-// 	mpFixExt2:      "FixExt2",
-// 	mpFixExt4:      "FixExt4",
-// 	mpFixExt8:      "FixExt8",
-// 	mpFixExt16:     "FixExt16",
-// 	mpStr8:         "Str8",
-// 	mpStr16:        "Str16",
-// 	mpStr32:        "Str32",
-// 	mpArray16:      "Array16",
-// 	mpArray32:      "Array32",
-// 	mpMap16:        "Map16",
-// 	mpMap32:        "Map32",
-// 	mpNegFixNumMin: "NegFixNumMin",
-// 	mpNegFixNumMax: "NegFixNumMax",
-// }
-
-func mpdesc(bd byte) string {
-	switch bd {
-	case mpNil:
-		return "nil"
-	case mpFalse:
-		return "false"
-	case mpTrue:
-		return "true"
-	case mpFloat, mpDouble:
-		return "float"
-	case mpUint8, mpUint16, mpUint32, mpUint64:
-		return "uint"
-	case mpInt8, mpInt16, mpInt32, mpInt64:
-		return "int"
-	default:
-		switch {
-		case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax:
-			return "int"
-		case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax:
-			return "int"
-		case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax:
-			return "string|bytes"
-		case bd == mpBin8, bd == mpBin16, bd == mpBin32:
-			return "bytes"
-		case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax:
-			return "array"
-		case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax:
-			return "map"
-		case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32:
-			return "ext"
-		default:
-			return "unknown"
-		}
-	}
-}
-
 // MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec
 // that the backend RPC service takes multiple arguments, which have been arranged
 // in sequence in the slice.
@@ -178,31 +94,21 @@ type msgpackContainerType struct {
 }
 
 var (
-	msgpackContainerStr = msgpackContainerType{
-		32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false,
-	}
-	msgpackContainerBin = msgpackContainerType{
-		0, 0, mpBin8, mpBin16, mpBin32, false, true, true,
-	}
-	msgpackContainerList = msgpackContainerType{
-		16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false,
-	}
-	msgpackContainerMap = msgpackContainerType{
-		16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false,
-	}
+	msgpackContainerStr  = msgpackContainerType{32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false}
+	msgpackContainerBin  = msgpackContainerType{0, 0, mpBin8, mpBin16, mpBin32, false, true, true}
+	msgpackContainerList = msgpackContainerType{16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false}
+	msgpackContainerMap  = msgpackContainerType{16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false}
 )
 
 //---------------------------------------------
 
 type msgpackEncDriver struct {
 	noBuiltInTypes
-	encDriverNoopContainerWriter
-	// encNoSeparator
+	encNoSeparator
 	e *Encoder
 	w encWriter
 	h *MsgpackHandle
 	x [8]byte
-	_ [3]uint64 // padding
 }
 
 func (e *msgpackEncDriver) EncodeNil() {
@@ -210,26 +116,10 @@ func (e *msgpackEncDriver) EncodeNil() {
 }
 
 func (e *msgpackEncDriver) EncodeInt(i int64) {
-	// if i >= 0 {
-	// 	e.EncodeUint(uint64(i))
-	// } else if false &&
-	if i > math.MaxInt8 {
-		if i <= math.MaxInt16 {
-			e.w.writen1(mpInt16)
-			bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
-		} else if i <= math.MaxInt32 {
-			e.w.writen1(mpInt32)
-			bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
-		} else {
-			e.w.writen1(mpInt64)
-			bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
-		}
+	if i >= 0 {
+		e.EncodeUint(uint64(i))
 	} else if i >= -32 {
-		if e.h.NoFixedNum {
-			e.w.writen2(mpInt8, byte(i))
-		} else {
-			e.w.writen1(byte(i))
-		}
+		e.w.writen1(byte(i))
 	} else if i >= math.MinInt8 {
 		e.w.writen2(mpInt8, byte(i))
 	} else if i >= math.MinInt16 {
@@ -246,11 +136,7 @@ func (e *msgpackEncDriver) EncodeInt(i int64) {
 
 func (e *msgpackEncDriver) EncodeUint(i uint64) {
 	if i <= math.MaxInt8 {
-		if e.h.NoFixedNum {
-			e.w.writen2(mpUint8, byte(i))
-		} else {
-			e.w.writen1(byte(i))
-		}
+		e.w.writen1(byte(i))
 	} else if i <= math.MaxUint8 {
 		e.w.writen2(mpUint8, byte(i))
 	} else if i <= math.MaxUint16 {
@@ -283,39 +169,6 @@ func (e *msgpackEncDriver) EncodeFloat64(f float64) {
 	bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
 }
 
-func (e *msgpackEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-		return
-	}
-	t = t.UTC()
-	sec, nsec := t.Unix(), uint64(t.Nanosecond())
-	var data64 uint64
-	var l = 4
-	if sec >= 0 && sec>>34 == 0 {
-		data64 = (nsec << 34) | uint64(sec)
-		if data64&0xffffffff00000000 != 0 {
-			l = 8
-		}
-	} else {
-		l = 12
-	}
-	if e.h.WriteExt {
-		e.encodeExtPreamble(mpTimeExtTagU, l)
-	} else {
-		e.writeContainerLen(msgpackContainerStr, l)
-	}
-	switch l {
-	case 4:
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(data64))
-	case 8:
-		bigenHelper{e.x[:8], e.w}.writeUint64(data64)
-	case 12:
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(nsec))
-		bigenHelper{e.x[:8], e.w}.writeUint64(uint64(sec))
-	}
-}
-
 func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) {
 	bs := ext.WriteExt(v)
 	if bs == nil {
@@ -326,7 +179,7 @@ func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Enc
 		e.encodeExtPreamble(uint8(xtag), len(bs))
 		e.w.writeb(bs)
 	} else {
-		e.EncodeStringBytes(cRAW, bs)
+		e.EncodeStringBytes(c_RAW, bs)
 	}
 }
 
@@ -360,38 +213,36 @@ func (e *msgpackEncDriver) encodeExtPreamble(xtag byte, l int) {
 	}
 }
 
-func (e *msgpackEncDriver) WriteArrayStart(length int) {
+func (e *msgpackEncDriver) EncodeArrayStart(length int) {
 	e.writeContainerLen(msgpackContainerList, length)
 }
 
-func (e *msgpackEncDriver) WriteMapStart(length int) {
+func (e *msgpackEncDriver) EncodeMapStart(length int) {
 	e.writeContainerLen(msgpackContainerMap, length)
 }
 
 func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
-	slen := len(s)
-	if c == cRAW && e.h.WriteExt {
-		e.writeContainerLen(msgpackContainerBin, slen)
+	if c == c_RAW && e.h.WriteExt {
+		e.writeContainerLen(msgpackContainerBin, len(s))
 	} else {
-		e.writeContainerLen(msgpackContainerStr, slen)
+		e.writeContainerLen(msgpackContainerStr, len(s))
 	}
-	if slen > 0 {
+	if len(s) > 0 {
 		e.w.writestr(s)
 	}
 }
 
+func (e *msgpackEncDriver) EncodeSymbol(v string) {
+	e.EncodeString(c_UTF8, v)
+}
+
 func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
-	if bs == nil {
-		e.EncodeNil()
-		return
-	}
-	slen := len(bs)
-	if c == cRAW && e.h.WriteExt {
-		e.writeContainerLen(msgpackContainerBin, slen)
+	if c == c_RAW && e.h.WriteExt {
+		e.writeContainerLen(msgpackContainerBin, len(bs))
 	} else {
-		e.writeContainerLen(msgpackContainerStr, slen)
+		e.writeContainerLen(msgpackContainerStr, len(bs))
 	}
-	if slen > 0 {
+	if len(bs) > 0 {
 		e.w.writeb(bs)
 	}
 }
@@ -413,18 +264,16 @@ func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) {
 //---------------------------------------------
 
 type msgpackDecDriver struct {
-	d *Decoder
-	r decReader // *Decoder decReader decReaderT
-	h *MsgpackHandle
-	// b      [scratchByteArrayLen]byte
+	d      *Decoder
+	r      decReader // *Decoder decReader decReaderT
+	h      *MsgpackHandle
+	b      [scratchByteArrayLen]byte
 	bd     byte
 	bdRead bool
 	br     bool // bytes reader
 	noBuiltInTypes
-	// noStreamingCodec
-	// decNoSeparator
-	decDriverNoopContainerReader
-	_ [3]uint64 // padding
+	noStreamingCodec
+	decNoSeparator
 }
 
 // Note: This returns either a primitive (int, bool, etc) for non-containers,
@@ -437,7 +286,7 @@ func (d *msgpackDecDriver) DecodeNaked() {
 		d.readNextBd()
 	}
 	bd := d.bd
-	n := d.d.n
+	n := &d.d.n
 	var decodeFurther bool
 
 	switch bd {
@@ -500,11 +349,11 @@ func (d *msgpackDecDriver) DecodeNaked() {
 				n.s = d.DecodeString()
 			} else {
 				n.v = valueTypeBytes
-				n.l = d.DecodeBytes(nil, false)
+				n.l = d.DecodeBytes(nil, false, false)
 			}
 		case bd == mpBin8, bd == mpBin16, bd == mpBin32:
 			n.v = valueTypeBytes
-			n.l = d.DecodeBytes(nil, false)
+			n.l = d.DecodeBytes(nil, false, false)
 		case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax:
 			n.v = valueTypeArray
 			decodeFurther = true
@@ -515,14 +364,9 @@ func (d *msgpackDecDriver) DecodeNaked() {
 			n.v = valueTypeExt
 			clen := d.readExtLen()
 			n.u = uint64(d.r.readn1())
-			if n.u == uint64(mpTimeExtTagU) {
-				n.v = valueTypeTime
-				n.t = d.decodeTime(clen)
-			} else {
-				n.l = d.r.readx(clen)
-			}
+			n.l = d.r.readx(clen)
 		default:
-			d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd))
+			d.d.errorf("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd)
 		}
 	}
 	if !decodeFurther {
@@ -536,7 +380,7 @@ func (d *msgpackDecDriver) DecodeNaked() {
 }
 
 // int can be decoded from msgpack type: intXXX or uintXXX
-func (d *msgpackDecDriver) DecodeInt64() (i int64) {
+func (d *msgpackDecDriver) DecodeInt(bitsize uint8) (i int64) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -564,7 +408,14 @@ func (d *msgpackDecDriver) DecodeInt64() (i int64) {
 		case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax:
 			i = int64(int8(d.bd))
 		default:
-			d.d.errorf("cannot decode signed integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
+			d.d.errorf("Unhandled single-byte unsigned integer value: %s: %x", msgBadDesc, d.bd)
+			return
+		}
+	}
+	// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
+	if bitsize > 0 {
+		if trunc := (i << (64 - bitsize)) >> (64 - bitsize); i != trunc {
+			d.d.errorf("Overflow int value: %v", i)
 			return
 		}
 	}
@@ -573,7 +424,7 @@ func (d *msgpackDecDriver) DecodeInt64() (i int64) {
 }
 
 // uint can be decoded from msgpack type: intXXX or uintXXX
-func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
+func (d *msgpackDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -590,28 +441,28 @@ func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
 		if i := int64(int8(d.r.readn1())); i >= 0 {
 			ui = uint64(i)
 		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			d.d.errorf("Assigning negative signed value: %v, to unsigned type", i)
 			return
 		}
 	case mpInt16:
 		if i := int64(int16(bigen.Uint16(d.r.readx(2)))); i >= 0 {
 			ui = uint64(i)
 		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			d.d.errorf("Assigning negative signed value: %v, to unsigned type", i)
 			return
 		}
 	case mpInt32:
 		if i := int64(int32(bigen.Uint32(d.r.readx(4)))); i >= 0 {
 			ui = uint64(i)
 		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			d.d.errorf("Assigning negative signed value: %v, to unsigned type", i)
 			return
 		}
 	case mpInt64:
 		if i := int64(bigen.Uint64(d.r.readx(8))); i >= 0 {
 			ui = uint64(i)
 		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			d.d.errorf("Assigning negative signed value: %v, to unsigned type", i)
 			return
 		}
 	default:
@@ -619,10 +470,17 @@ func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
 		case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax:
 			ui = uint64(d.bd)
 		case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax:
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", int(d.bd))
+			d.d.errorf("Assigning negative signed value: %v, to unsigned type", int(d.bd))
 			return
 		default:
-			d.d.errorf("cannot decode unsigned integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
+			d.d.errorf("Unhandled single-byte unsigned integer value: %s: %x", msgBadDesc, d.bd)
+			return
+		}
+	}
+	// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
+	if bitsize > 0 {
+		if trunc := (ui << (64 - bitsize)) >> (64 - bitsize); ui != trunc {
+			d.d.errorf("Overflow uint value: %v", ui)
 			return
 		}
 	}
@@ -631,7 +489,7 @@ func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
 }
 
 // float can either be decoded from msgpack type: float, double or intX
-func (d *msgpackDecDriver) DecodeFloat64() (f float64) {
+func (d *msgpackDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -640,7 +498,11 @@ func (d *msgpackDecDriver) DecodeFloat64() (f float64) {
 	} else if d.bd == mpDouble {
 		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
 	} else {
-		f = float64(d.DecodeInt64())
+		f = float64(d.DecodeInt(0))
+	}
+	if chkOverflow32 && chkOvf.Float32(f) {
+		d.d.errorf("msgpack: float32 overflow: %v", f)
+		return
 	}
 	d.bdRead = false
 	return
@@ -656,45 +518,25 @@ func (d *msgpackDecDriver) DecodeBool() (b bool) {
 	} else if d.bd == mpTrue || d.bd == 1 {
 		b = true
 	} else {
-		d.d.errorf("cannot decode bool: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
+		d.d.errorf("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd)
 		return
 	}
 	d.bdRead = false
 	return
 }
 
-func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+func (d *msgpackDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
-
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	bd := d.bd
-	// DecodeBytes could be from: bin str fixstr fixarray array ...
 	var clen int
-	vt := d.ContainerType()
-	switch vt {
-	case valueTypeBytes:
-		// valueTypeBytes may be a mpBin or an mpStr container
-		if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 {
-			clen = d.readContainerLen(msgpackContainerBin)
-		} else {
-			clen = d.readContainerLen(msgpackContainerStr)
-		}
-	case valueTypeString:
+	// ignore isstring. Expect that the bytes may be found from msgpackContainerStr or msgpackContainerBin
+	if bd := d.bd; bd == mpBin8 || bd == mpBin16 || bd == mpBin32 {
+		clen = d.readContainerLen(msgpackContainerBin)
+	} else {
 		clen = d.readContainerLen(msgpackContainerStr)
-	case valueTypeArray:
-		if zerocopy && len(bs) == 0 {
-			bs = d.d.b[:]
-		}
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	default:
-		d.d.errorf("invalid container type: expecting bin|str|array, got: 0x%x", uint8(vt))
-		return
 	}
-
-	// these are (bin|str)(8|16|32)
+	// println("DecodeBytes: clen: ", clen)
 	d.bdRead = false
 	// bytes may be nil, so handle it. if nil, clen=-1.
 	if clen < 0 {
@@ -704,18 +546,14 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
 		if d.br {
 			return d.r.readx(clen)
 		} else if len(bs) == 0 {
-			bs = d.d.b[:]
+			bs = d.b[:]
 		}
 	}
-	return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
+	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
 }
 
 func (d *msgpackDecDriver) DecodeString() (s string) {
-	return string(d.DecodeBytes(d.d.b[:], true))
-}
-
-func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) {
-	return d.DecodeBytes(d.d.b[:], true)
+	return string(d.DecodeBytes(d.b[:], true, true))
 }
 
 func (d *msgpackDecDriver) readNextBd() {
@@ -731,9 +569,6 @@ func (d *msgpackDecDriver) uncacheRead() {
 }
 
 func (d *msgpackDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	bd := d.bd
 	if bd == mpNil {
 		return valueTypeNil
@@ -748,10 +583,9 @@ func (d *msgpackDecDriver) ContainerType() (vt valueType) {
 		return valueTypeArray
 	} else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) {
 		return valueTypeMap
+	} else {
+		// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
 	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
 	return valueTypeUnset
 }
 
@@ -761,7 +595,7 @@ func (d *msgpackDecDriver) TryDecodeAsNil() (v bool) {
 	}
 	if d.bd == mpNil {
 		d.bdRead = false
-		return true
+		v = true
 	}
 	return
 }
@@ -779,7 +613,7 @@ func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int)
 	} else if (ct.bFixMin & bd) == ct.bFixMin {
 		clen = int(ct.bFixMin ^ bd)
 	} else {
-		d.d.errorf("cannot read container length: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd)
+		d.d.errorf("readContainerLen: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd)
 		return
 	}
 	d.bdRead = false
@@ -787,16 +621,10 @@ func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int)
 }
 
 func (d *msgpackDecDriver) ReadMapStart() int {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	return d.readContainerLen(msgpackContainerMap)
 }
 
 func (d *msgpackDecDriver) ReadArrayStart() int {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	return d.readContainerLen(msgpackContainerList)
 }
 
@@ -827,60 +655,9 @@ func (d *msgpackDecDriver) readExtLen() (clen int) {
 	return
 }
 
-func (d *msgpackDecDriver) DecodeTime() (t time.Time) {
-	// decode time from string bytes or ext
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == mpNil {
-		d.bdRead = false
-		return
-	}
-	var clen int
-	switch d.ContainerType() {
-	case valueTypeBytes, valueTypeString:
-		clen = d.readContainerLen(msgpackContainerStr)
-	default:
-		// expect to see mpFixExt4,-1 OR mpFixExt8,-1 OR mpExt8,12,-1
-		d.bdRead = false
-		b2 := d.r.readn1()
-		if d.bd == mpFixExt4 && b2 == mpTimeExtTagU {
-			clen = 4
-		} else if d.bd == mpFixExt8 && b2 == mpTimeExtTagU {
-			clen = 8
-		} else if d.bd == mpExt8 && b2 == 12 && d.r.readn1() == mpTimeExtTagU {
-			clen = 12
-		} else {
-			d.d.errorf("invalid bytes for decoding time as extension: got 0x%x, 0x%x", d.bd, b2)
-			return
-		}
-	}
-	return d.decodeTime(clen)
-}
-
-func (d *msgpackDecDriver) decodeTime(clen int) (t time.Time) {
-	// bs = d.r.readx(clen)
-	d.bdRead = false
-	switch clen {
-	case 4:
-		t = time.Unix(int64(bigen.Uint32(d.r.readx(4))), 0).UTC()
-	case 8:
-		tv := bigen.Uint64(d.r.readx(8))
-		t = time.Unix(int64(tv&0x00000003ffffffff), int64(tv>>34)).UTC()
-	case 12:
-		nsec := bigen.Uint32(d.r.readx(4))
-		sec := bigen.Uint64(d.r.readx(8))
-		t = time.Unix(int64(sec), int64(nsec)).UTC()
-	default:
-		d.d.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen)
-		return
-	}
-	return
-}
-
 func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
 	if xtag > 0xff {
-		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
+		d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
 		return
 	}
 	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
@@ -901,15 +678,15 @@ func (d *msgpackDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs
 	}
 	xbd := d.bd
 	if xbd == mpBin8 || xbd == mpBin16 || xbd == mpBin32 {
-		xbs = d.DecodeBytes(nil, true)
+		xbs = d.DecodeBytes(nil, false, true)
 	} else if xbd == mpStr8 || xbd == mpStr16 || xbd == mpStr32 ||
 		(xbd >= mpFixStrMin && xbd <= mpFixStrMax) {
-		xbs = d.DecodeStringAsBytes()
+		xbs = d.DecodeBytes(nil, true, true)
 	} else {
 		clen := d.readExtLen()
 		xtag = d.r.readn1()
 		if verifyTag && xtag != tag {
-			d.d.errorf("wrong extension tag - got %b, expecting %v", xtag, tag)
+			d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", xtag, tag)
 			return
 		}
 		xbs = d.r.readx(clen)
@@ -927,9 +704,6 @@ type MsgpackHandle struct {
 	// RawToString controls how raw bytes are decoded into a nil interface{}.
 	RawToString bool
 
-	// NoFixedNum says to output all signed integers as 2-bytes, never as 1-byte fixednum.
-	NoFixedNum bool
-
 	// WriteExt flag supports encoding configured extensions with extension tags.
 	// It also controls whether other elements of the new spec are encoded (ie Str8).
 	//
@@ -941,19 +715,11 @@ type MsgpackHandle struct {
 	// type is provided (e.g. decoding into a nil interface{}), you get back
 	// a []byte or string based on the setting of RawToString.
 	WriteExt bool
-
 	binaryEncodingType
-	noElemSeparators
-
-	// _ [1]uint64 // padding
 }
 
-// Name returns the name of the handle: msgpack
-func (h *MsgpackHandle) Name() string { return "msgpack" }
-
-// SetBytesExt sets an extension
 func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
+	return h.SetExt(rt, tag, &setExtWrapper{b: ext})
 }
 
 func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver {
@@ -961,7 +727,7 @@ func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver {
 }
 
 func (h *MsgpackHandle) newDecDriver(d *Decoder) decDriver {
-	return &msgpackDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+	return &msgpackDecDriver{d: d, r: d.r, h: h, br: d.bytes}
 }
 
 func (e *msgpackEncDriver) reset() {
@@ -969,7 +735,7 @@ func (e *msgpackEncDriver) reset() {
 }
 
 func (d *msgpackDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
+	d.r = d.d.r
 	d.bd, d.bdRead = 0, false
 }
 
@@ -991,7 +757,7 @@ func (c *msgpackSpecRpcCodec) WriteRequest(r *rpc.Request, body interface{}) err
 		bodyArr = []interface{}{body}
 	}
 	r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr}
-	return c.write(r2, nil, false)
+	return c.write(r2, nil, false, true)
 }
 
 func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
@@ -1003,7 +769,7 @@ func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) e
 		body = nil
 	}
 	r2 := []interface{}{1, uint32(r.Seq), moe, body}
-	return c.write(r2, nil, false)
+	return c.write(r2, nil, false, true)
 }
 
 func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error {
@@ -1023,6 +789,7 @@ func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error {
 }
 
 func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
+
 	if c.isClosed() {
 		return io.EOF
 	}
@@ -1036,34 +803,28 @@ func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint
 	// 	err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, bs1)
 	// 	return
 	// }
-	var ba [1]byte
-	var n int
-	for {
-		n, err = c.r.Read(ba[:])
-		if err != nil {
-			return
-		}
-		if n == 1 {
-			break
-		}
+	var b byte
+	b, err = c.br.ReadByte()
+	if err != nil {
+		return
 	}
-
-	var b = ba[0]
 	if b != fia {
-		err = fmt.Errorf("not array - %s %x/%s", msgBadDesc, b, mpdesc(b))
-	} else {
-		err = c.read(&b)
-		if err == nil {
-			if b != expectTypeByte {
-				err = fmt.Errorf("%s - expecting %v but got %x/%s",
-					msgBadDesc, expectTypeByte, b, mpdesc(b))
-			} else {
-				err = c.read(msgid)
-				if err == nil {
-					err = c.read(methodOrError)
-				}
-			}
-		}
+		err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, b)
+		return
+	}
+
+	if err = c.read(&b); err != nil {
+		return
+	}
+	if b != expectTypeByte {
+		err = fmt.Errorf("Unexpected byte descriptor in header. Expecting %v. Received %v", expectTypeByte, b)
+		return
+	}
+	if err = c.read(msgid); err != nil {
+		return
+	}
+	if err = c.read(methodOrError); err != nil {
+		return
 	}
 	return
 }
@@ -1076,8 +837,7 @@ type msgpackSpecRpc struct{}
 
 // MsgpackSpecRpc implements Rpc using the communication protocol defined in
 // the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md .
-//
-// See GoRpc documentation, for information on buffering for better performance.
+// Its methods (ServerCodec and ClientCodec) return values that implement RpcCodecBuffered.
 var MsgpackSpecRpc msgpackSpecRpc
 
 func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
diff --git a/vendor/github.com/ugorji/go/codec/noop.go b/vendor/github.com/ugorji/go/codec/noop.go
new file mode 100644
index 000000000..cfee3d084
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/noop.go
@@ -0,0 +1,213 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"math/rand"
+	"time"
+)
+
+// NoopHandle returns a no-op handle. It basically does nothing.
+// It is only useful for benchmarking, as it gives an idea of the
+// overhead from the codec framework.
+//
+// LIBRARY USERS: *** DO NOT USE ***
+func NoopHandle(slen int) *noopHandle {
+	h := noopHandle{}
+	h.rand = rand.New(rand.NewSource(time.Now().UnixNano()))
+	h.B = make([][]byte, slen)
+	h.S = make([]string, slen)
+	for i := 0; i < len(h.S); i++ {
+		b := make([]byte, i+1)
+		for j := 0; j < len(b); j++ {
+			b[j] = 'a' + byte(i)
+		}
+		h.B[i] = b
+		h.S[i] = string(b)
+	}
+	return &h
+}
+
+// noopHandle does nothing.
+// It is used to simulate the overhead of the codec framework.
+type noopHandle struct {
+	BasicHandle
+	binaryEncodingType
+	noopDrv // noopDrv is unexported here, so we can get a copy of it when needed.
+}
+
+type noopDrv struct {
+	d    *Decoder
+	e    *Encoder
+	i    int
+	S    []string
+	B    [][]byte
+	mks  []bool    // stack. if map (true), else if array (false)
+	mk   bool      // top of stack. what container are we on? map or array?
+	ct   valueType // last response for IsContainerType.
+	cb   int       // counter for ContainerType
+	rand *rand.Rand
+}
+
+func (h *noopDrv) r(v int) int { return h.rand.Intn(v) }
+func (h *noopDrv) m(v int) int { h.i++; return h.i % v }
+
+func (h *noopDrv) newEncDriver(e *Encoder) encDriver { h.e = e; return h }
+func (h *noopDrv) newDecDriver(d *Decoder) decDriver { h.d = d; return h }
+
+func (h *noopDrv) reset()       {}
+func (h *noopDrv) uncacheRead() {}
+
+// --- encDriver
+
+// stack functions (for map and array)
+func (h *noopDrv) start(b bool) {
+	// println("start", len(h.mks)+1)
+	h.mks = append(h.mks, b)
+	h.mk = b
+}
+func (h *noopDrv) end() {
+	// println("end: ", len(h.mks)-1)
+	h.mks = h.mks[:len(h.mks)-1]
+	if len(h.mks) > 0 {
+		h.mk = h.mks[len(h.mks)-1]
+	} else {
+		h.mk = false
+	}
+}
+
+func (h *noopDrv) EncodeBuiltin(rt uintptr, v interface{}) {}
+func (h *noopDrv) EncodeNil()                              {}
+func (h *noopDrv) EncodeInt(i int64)                       {}
+func (h *noopDrv) EncodeUint(i uint64)                     {}
+func (h *noopDrv) EncodeBool(b bool)                       {}
+func (h *noopDrv) EncodeFloat32(f float32)                 {}
+func (h *noopDrv) EncodeFloat64(f float64)                 {}
+func (h *noopDrv) EncodeRawExt(re *RawExt, e *Encoder)     {}
+func (h *noopDrv) EncodeArrayStart(length int)             { h.start(true) }
+func (h *noopDrv) EncodeMapStart(length int)               { h.start(false) }
+func (h *noopDrv) EncodeEnd()                              { h.end() }
+
+func (h *noopDrv) EncodeString(c charEncoding, v string)      {}
+func (h *noopDrv) EncodeSymbol(v string)                      {}
+func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {}
+
+func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {}
+
+// ---- decDriver
+func (h *noopDrv) initReadNext()                              {}
+func (h *noopDrv) CheckBreak() bool                           { return false }
+func (h *noopDrv) IsBuiltinType(rt uintptr) bool              { return false }
+func (h *noopDrv) DecodeBuiltin(rt uintptr, v interface{})    {}
+func (h *noopDrv) DecodeInt(bitsize uint8) (i int64)          { return int64(h.m(15)) }
+func (h *noopDrv) DecodeUint(bitsize uint8) (ui uint64)       { return uint64(h.m(35)) }
+func (h *noopDrv) DecodeFloat(chkOverflow32 bool) (f float64) { return float64(h.m(95)) }
+func (h *noopDrv) DecodeBool() (b bool)                       { return h.m(2) == 0 }
+func (h *noopDrv) DecodeString() (s string)                   { return h.S[h.m(8)] }
+
+// func (h *noopDrv) DecodeStringAsBytes(bs []byte) []byte       { return h.DecodeBytes(bs) }
+
+func (h *noopDrv) DecodeBytes(bs []byte, isstring, zerocopy bool) []byte { return h.B[h.m(len(h.B))] }
+
+func (h *noopDrv) ReadEnd() { h.end() }
+
+// toggle map/slice
+func (h *noopDrv) ReadMapStart() int   { h.start(true); return h.m(10) }
+func (h *noopDrv) ReadArrayStart() int { h.start(false); return h.m(10) }
+
+func (h *noopDrv) ContainerType() (vt valueType) {
+	// return h.m(2) == 0
+	// handle kStruct, which will bomb is it calls this and doesn't get back a map or array.
+	// consequently, if the return value is not map or array, reset it to one of them based on h.m(7) % 2
+	// for kstruct: at least one out of every 2 times, return one of valueTypeMap or Array (else kstruct bombs)
+	// however, every 10th time it is called, we just return something else.
+	var vals = [...]valueType{valueTypeArray, valueTypeMap}
+	//  ------------ TAKE ------------
+	// if h.cb%2 == 0 {
+	// 	if h.ct == valueTypeMap || h.ct == valueTypeArray {
+	// 	} else {
+	// 		h.ct = vals[h.m(2)]
+	// 	}
+	// } else if h.cb%5 == 0 {
+	// 	h.ct = valueType(h.m(8))
+	// } else {
+	// 	h.ct = vals[h.m(2)]
+	// }
+	//  ------------ TAKE ------------
+	// if h.cb%16 == 0 {
+	// 	h.ct = valueType(h.cb % 8)
+	// } else {
+	// 	h.ct = vals[h.cb%2]
+	// }
+	h.ct = vals[h.cb%2]
+	h.cb++
+	return h.ct
+
+	// if h.ct == valueTypeNil || h.ct == valueTypeString || h.ct == valueTypeBytes {
+	// 	return h.ct
+	// }
+	// return valueTypeUnset
+	// TODO: may need to tweak this so it works.
+	// if h.ct == valueTypeMap && vt == valueTypeArray || h.ct == valueTypeArray && vt == valueTypeMap {
+	// 	h.cb = !h.cb
+	// 	h.ct = vt
+	// 	return h.cb
+	// }
+	// // go in a loop and check it.
+	// h.ct = vt
+	// h.cb = h.m(7) == 0
+	// return h.cb
+}
+func (h *noopDrv) TryDecodeAsNil() bool {
+	if h.mk {
+		return false
+	} else {
+		return h.m(8) == 0
+	}
+}
+func (h *noopDrv) DecodeExt(rv interface{}, xtag uint64, ext Ext) uint64 {
+	return 0
+}
+
+func (h *noopDrv) DecodeNaked() {
+	// use h.r (random) not h.m() because h.m() could cause the same value to be given.
+	var sk int
+	if h.mk {
+		// if mapkey, do not support values of nil OR bytes, array, map or rawext
+		sk = h.r(7) + 1
+	} else {
+		sk = h.r(12)
+	}
+	n := &h.d.n
+	switch sk {
+	case 0:
+		n.v = valueTypeNil
+	case 1:
+		n.v, n.b = valueTypeBool, false
+	case 2:
+		n.v, n.b = valueTypeBool, true
+	case 3:
+		n.v, n.i = valueTypeInt, h.DecodeInt(64)
+	case 4:
+		n.v, n.u = valueTypeUint, h.DecodeUint(64)
+	case 5:
+		n.v, n.f = valueTypeFloat, h.DecodeFloat(true)
+	case 6:
+		n.v, n.f = valueTypeFloat, h.DecodeFloat(false)
+	case 7:
+		n.v, n.s = valueTypeString, h.DecodeString()
+	case 8:
+		n.v, n.l = valueTypeBytes, h.B[h.m(len(h.B))]
+	case 9:
+		n.v = valueTypeArray
+	case 10:
+		n.v = valueTypeMap
+	default:
+		n.v = valueTypeExt
+		n.u = h.DecodeUint(64)
+		n.l = h.B[h.m(len(h.B))]
+	}
+	h.ct = n.v
+	return
+}
diff --git a/vendor/github.com/ugorji/go/codec/prebuild.go b/vendor/github.com/ugorji/go/codec/prebuild.go
new file mode 100644
index 000000000..2353263e8
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/prebuild.go
@@ -0,0 +1,3 @@
+package codec
+
+//go:generate bash prebuild.sh
diff --git a/vendor/github.com/ugorji/go/codec/prebuild.sh b/vendor/github.com/ugorji/go/codec/prebuild.sh
new file mode 100755
index 000000000..909f4bb0f
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/prebuild.sh
@@ -0,0 +1,199 @@
+#!/bin/bash
+
+# _needgen is a helper function to tell if we need to generate files for msgp, codecgen.
+_needgen() {
+    local a="$1"
+    zneedgen=0
+    if [[ ! -e "$a" ]]
+    then
+        zneedgen=1
+        echo 1
+        return 0
+    fi 
+    for i in `ls -1 *.go.tmpl gen.go values_test.go`
+    do
+        if [[ "$a" -ot "$i" ]]
+        then
+            zneedgen=1
+            echo 1
+            return 0
+        fi 
+    done 
+    echo 0
+}
+
+# _build generates fast-path.go and gen-helper.go.
+# 
+# It is needed because there is some dependency between the generated code
+# and the other classes. Consequently, we have to totally remove the 
+# generated files and put stubs in place, before calling "go run" again
+# to recreate them.
+_build() {
+    if ! [[ "${zforce}" == "1" ||
+                "1" == $( _needgen "fast-path.generated.go" ) ||
+                "1" == $( _needgen "gen-helper.generated.go" ) ||
+                "1" == $( _needgen "gen.generated.go" ) ||
+                1 == 0 ]]
+    then
+        return 0
+    fi 
+
+   # echo "Running prebuild"
+    if [ "${zbak}" == "1" ] 
+    then
+        # echo "Backing up old generated files"
+        _zts=`date '+%m%d%Y_%H%M%S'`
+        _gg=".generated.go"
+        [ -e "gen-helper${_gg}" ] && mv gen-helper${_gg} gen-helper${_gg}__${_zts}.bak
+        [ -e "fast-path${_gg}" ] && mv fast-path${_gg} fast-path${_gg}__${_zts}.bak
+        # [ -e "safe${_gg}" ] && mv safe${_gg} safe${_gg}__${_zts}.bak
+        # [ -e "unsafe${_gg}" ] && mv unsafe${_gg} unsafe${_gg}__${_zts}.bak
+    else 
+        rm -f fast-path.generated.go gen.generated.go gen-helper.generated.go \
+           *safe.generated.go *_generated_test.go *.generated_ffjson_expose.go
+    fi
+
+    cat > gen.generated.go <<EOF
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+// DO NOT EDIT. THIS FILE IS AUTO-GENERATED FROM gen-dec-(map|array).go.tmpl
+
+const genDecMapTmpl = \`
+EOF
+
+    cat >> gen.generated.go < gen-dec-map.go.tmpl
+
+    cat >> gen.generated.go <<EOF
+\`
+
+const genDecListTmpl = \`
+EOF
+
+    cat >> gen.generated.go < gen-dec-array.go.tmpl
+
+    cat >> gen.generated.go <<EOF
+\`
+
+EOF
+
+    cat > gen-from-tmpl.codec.generated.go <<EOF
+package codec 
+import "io"
+func GenInternalGoFile(r io.Reader, w io.Writer, safe bool) error {
+return genInternalGoFile(r, w, safe)
+}
+EOF
+    
+    cat > gen-from-tmpl.generated.go <<EOF
+//+build ignore
+
+package main
+
+//import "flag"
+import "ugorji.net/codec"
+import "os"
+
+func run(fnameIn, fnameOut string, safe bool) {
+fin, err := os.Open(fnameIn)
+if err != nil { panic(err) }
+defer fin.Close()
+fout, err := os.Create(fnameOut)
+if err != nil { panic(err) }
+defer fout.Close()
+err = codec.GenInternalGoFile(fin, fout, safe)
+if err != nil { panic(err) }
+}
+
+func main() {
+// do not make safe/unsafe variants. 
+// Instead, depend on escape analysis, and place string creation and usage appropriately.
+// run("unsafe.go.tmpl", "safe.generated.go", true)
+// run("unsafe.go.tmpl", "unsafe.generated.go", false)
+run("fast-path.go.tmpl", "fast-path.generated.go", false)
+run("gen-helper.go.tmpl", "gen-helper.generated.go", false)
+}
+
+EOF
+    go run -tags=notfastpath gen-from-tmpl.generated.go && \
+        rm -f gen-from-tmpl.*generated.go 
+}
+
+_codegenerators() {
+    if [[ $zforce == "1" || 
+                "1" == $( _needgen "values_codecgen${zsfx}" ) ||
+                "1" == $( _needgen "values_msgp${zsfx}" ) ||
+                "1" == $( _needgen "values_ffjson${zsfx}" ) ||
+                1 == 0 ]] 
+    then
+        # codecgen creates some temporary files in the directory (main, pkg).
+        # Consequently, we should start msgp and ffjson first, and also put a small time latency before
+        # starting codecgen.
+        # Without this, ffjson chokes on one of the temporary files from codecgen.
+        if [[ $zexternal == "1" ]]
+        then 
+            echo "ffjson ... " && \
+                ffjson -w values_ffjson${zsfx} $zfin &
+            zzzIdFF=$!
+            echo "msgp ... " && \
+                msgp -tests=false -o=values_msgp${zsfx} -file=$zfin &
+            zzzIdMsgp=$!
+            
+            sleep 1 # give ffjson and msgp some buffer time. see note above.
+        fi
+        
+        echo "codecgen - !unsafe ... " && \
+            codecgen -rt codecgen -t 'x,codecgen,!unsafe' -o values_codecgen${zsfx} -d 19780 $zfin &
+        zzzIdC=$!
+        echo "codecgen - unsafe ... " && \
+            codecgen  -u -rt codecgen -t 'x,codecgen,unsafe' -o values_codecgen_unsafe${zsfx} -d 19781 $zfin &
+        zzzIdCU=$!
+        wait $zzzIdC $zzzIdCU $zzzIdMsgp $zzzIdFF && \
+            # remove (M|Unm)arshalJSON implementations, so they don't conflict with encoding/json bench \
+            if [[ $zexternal == "1" ]]
+            then
+                sed -i 's+ MarshalJSON(+ _MarshalJSON(+g' values_ffjson${zsfx} && \
+                    sed -i 's+ UnmarshalJSON(+ _UnmarshalJSON(+g' values_ffjson${zsfx}
+            fi && \
+            echo "generators done!" && \
+            true
+    fi 
+}
+
+# _init reads the arguments and sets up the flags
+_init() {
+OPTIND=1
+while getopts "fbx" flag
+do
+    case "x$flag" in 
+        'xf') zforce=1;;
+        'xb') zbak=1;;
+        'xx') zexternal=1;;
+        *) echo "prebuild.sh accepts [-fbx] only"; return 1;;
+    esac
+done
+shift $((OPTIND-1))
+OPTIND=1
+}
+
+# main script.
+# First ensure that this is being run from the basedir (i.e. dirname of script is .)
+if [ "." = `dirname $0` ]
+then
+    zmydir=`pwd`
+    zfin="test_values.generated.go"
+    zsfx="_generated_test.go"
+    # rm -f *_generated_test.go 
+    rm -f codecgen-*.go && \
+        _init "$@" && \
+        _build && \
+        cp $zmydir/values_test.go $zmydir/$zfin && \
+        _codegenerators && \
+        echo prebuild done successfully
+    rm -f $zmydir/$zfin
+else
+    echo "Script must be run from the directory it resides in"
+fi 
+
diff --git a/vendor/github.com/ugorji/go/codec/rpc.go b/vendor/github.com/ugorji/go/codec/rpc.go
index 9fb3c0149..8062bed31 100644
--- a/vendor/github.com/ugorji/go/codec/rpc.go
+++ b/vendor/github.com/ugorji/go/codec/rpc.go
@@ -1,152 +1,127 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
 
 import (
 	"bufio"
-	"errors"
 	"io"
 	"net/rpc"
 	"sync"
 )
 
+// rpcEncodeTerminator allows a handler specify a []byte terminator to send after each Encode.
+//
+// Some codecs like json need to put a space after each encoded value, to serve as a
+// delimiter for things like numbers (else json codec will continue reading till EOF).
+type rpcEncodeTerminator interface {
+	rpcEncodeTerminate() []byte
+}
+
 // Rpc provides a rpc Server or Client Codec for rpc communication.
 type Rpc interface {
 	ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
 	ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
 }
 
-// RPCOptions holds options specific to rpc functionality
-type RPCOptions struct {
-	// RPCNoBuffer configures whether we attempt to buffer reads and writes during RPC calls.
-	//
-	// Set RPCNoBuffer=true to turn buffering off.
-	// Buffering can still be done if buffered connections are passed in, or
-	// buffering is configured on the handle.
-	RPCNoBuffer bool
+// RpcCodecBuffered allows access to the underlying bufio.Reader/Writer
+// used by the rpc connection. It accommodates use-cases where the connection
+// should be used by rpc and non-rpc functions, e.g. streaming a file after
+// sending an rpc response.
+type RpcCodecBuffered interface {
+	BufferedReader() *bufio.Reader
+	BufferedWriter() *bufio.Writer
 }
 
+// -------------------------------------
+
 // rpcCodec defines the struct members and common methods.
 type rpcCodec struct {
-	c io.Closer
-	r io.Reader
-	w io.Writer
-	f ioFlusher
-
+	rwc io.ReadWriteCloser
 	dec *Decoder
 	enc *Encoder
-	// bw  *bufio.Writer
-	// br  *bufio.Reader
-	mu sync.Mutex
-	h  Handle
+	bw  *bufio.Writer
+	br  *bufio.Reader
+	mu  sync.Mutex
+	h   Handle
 
-	cls    bool
-	clsmu  sync.RWMutex
-	clsErr error
+	cls   bool
+	clsmu sync.RWMutex
 }
 
 func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
-	// return newRPCCodec2(bufio.NewReader(conn), bufio.NewWriter(conn), conn, h)
-	return newRPCCodec2(conn, conn, conn, h)
-}
-
-func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
-	// defensive: ensure that jsonH has TermWhitespace turned on.
-	if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
-		panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
-	}
-	// always ensure that we use a flusher, and always flush what was written to the connection.
-	// we lose nothing by using a buffered writer internally.
-	f, ok := w.(ioFlusher)
-	bh := h.getBasicHandle()
-	if !bh.RPCNoBuffer {
-		if bh.WriterBufferSize <= 0 {
-			if !ok {
-				bw := bufio.NewWriter(w)
-				f, w = bw, bw
-			}
-		}
-		if bh.ReaderBufferSize <= 0 {
-			if _, ok = w.(ioPeeker); !ok {
-				if _, ok = w.(ioBuffered); !ok {
-					br := bufio.NewReader(r)
-					r = br
-				}
-			}
-		}
-	}
+	bw := bufio.NewWriter(conn)
+	br := bufio.NewReader(conn)
 	return rpcCodec{
-		c:   c,
-		w:   w,
-		r:   r,
-		f:   f,
+		rwc: conn,
+		bw:  bw,
+		br:  br,
+		enc: NewEncoder(bw, h),
+		dec: NewDecoder(br, h),
 		h:   h,
-		enc: NewEncoder(w, h),
-		dec: NewDecoder(r, h),
 	}
 }
 
-func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
+func (c *rpcCodec) BufferedReader() *bufio.Reader {
+	return c.br
+}
+
+func (c *rpcCodec) BufferedWriter() *bufio.Writer {
+	return c.bw
+}
+
+func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2, doFlush bool) (err error) {
 	if c.isClosed() {
-		return c.clsErr
+		return io.EOF
 	}
-	err = c.enc.Encode(obj1)
-	if err == nil {
-		if writeObj2 {
-			err = c.enc.Encode(obj2)
-		}
-		// if err == nil && c.f != nil {
-		// 	err = c.f.Flush()
-		// }
+	if err = c.enc.Encode(obj1); err != nil {
+		return
+	}
+	t, tOk := c.h.(rpcEncodeTerminator)
+	if tOk {
+		c.bw.Write(t.rpcEncodeTerminate())
 	}
-	if c.f != nil {
-		if err == nil {
-			err = c.f.Flush()
-		} else {
-			_ = c.f.Flush() // swallow flush error, so we maintain prior error on write
+	if writeObj2 {
+		if err = c.enc.Encode(obj2); err != nil {
+			return
 		}
+		if tOk {
+			c.bw.Write(t.rpcEncodeTerminate())
+		}
+	}
+	if doFlush {
+		return c.bw.Flush()
 	}
 	return
 }
 
-func (c *rpcCodec) swallow(err *error) {
-	defer panicToErr(c.dec, err)
-	c.dec.swallow()
-}
-
 func (c *rpcCodec) read(obj interface{}) (err error) {
 	if c.isClosed() {
-		return c.clsErr
+		return io.EOF
 	}
-	//If nil is passed in, we should read and discard
+	//If nil is passed in, we should still attempt to read content to nowhere.
 	if obj == nil {
-		// var obj2 interface{}
-		// return c.dec.Decode(&obj2)
-		c.swallow(&err)
-		return
+		var obj2 interface{}
+		return c.dec.Decode(&obj2)
 	}
 	return c.dec.Decode(obj)
 }
 
-func (c *rpcCodec) isClosed() (b bool) {
-	if c.c != nil {
-		c.clsmu.RLock()
-		b = c.cls
-		c.clsmu.RUnlock()
-	}
-	return
+func (c *rpcCodec) isClosed() bool {
+	c.clsmu.RLock()
+	x := c.cls
+	c.clsmu.RUnlock()
+	return x
 }
 
 func (c *rpcCodec) Close() error {
-	if c.c == nil || c.isClosed() {
-		return c.clsErr
+	if c.isClosed() {
+		return io.EOF
 	}
 	c.clsmu.Lock()
 	c.cls = true
-	c.clsErr = c.c.Close()
 	c.clsmu.Unlock()
-	return c.clsErr
+	return c.rwc.Close()
 }
 
 func (c *rpcCodec) ReadResponseBody(body interface{}) error {
@@ -163,13 +138,13 @@ func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
 	// Must protect for concurrent access as per API
 	c.mu.Lock()
 	defer c.mu.Unlock()
-	return c.write(r, body, true)
+	return c.write(r, body, true, true)
 }
 
 func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
 	c.mu.Lock()
 	defer c.mu.Unlock()
-	return c.write(r, body, true)
+	return c.write(r, body, true, true)
 }
 
 func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
@@ -191,36 +166,7 @@ func (c *goRpcCodec) ReadRequestBody(body interface{}) error {
 type goRpc struct{}
 
 // GoRpc implements Rpc using the communication protocol defined in net/rpc package.
-//
-// Note: network connection (from net.Dial, of type io.ReadWriteCloser) is not buffered.
-//
-// For performance, you should configure WriterBufferSize and ReaderBufferSize on the handle.
-// This ensures we use an adequate buffer during reading and writing.
-// If not configured, we will internally initialize and use a buffer during reads and writes.
-// This can be turned off via the RPCNoBuffer option on the Handle.
-//   var handle codec.JsonHandle
-//   handle.RPCNoBuffer = true // turns off attempt by rpc module to initialize a buffer
-//
-// Example 1: one way of configuring buffering explicitly:
-//   var handle codec.JsonHandle // codec handle
-//   handle.ReaderBufferSize = 1024
-//   handle.WriterBufferSize = 1024
-//   var conn io.ReadWriteCloser // connection got from a socket
-//   var serverCodec = GoRpc.ServerCodec(conn, handle)
-//   var clientCodec = GoRpc.ClientCodec(conn, handle)
-//
-// Example 2: you can also explicitly create a buffered connection yourself,
-// and not worry about configuring the buffer sizes in the Handle.
-//   var handle codec.Handle     // codec handle
-//   var conn io.ReadWriteCloser // connection got from a socket
-//   var bufconn = struct {      // bufconn here is a buffered io.ReadWriteCloser
-//       io.Closer
-//       *bufio.Reader
-//       *bufio.Writer
-//   }{conn, bufio.NewReader(conn), bufio.NewWriter(conn)}
-//   var serverCodec = GoRpc.ServerCodec(bufconn, handle)
-//   var clientCodec = GoRpc.ClientCodec(bufconn, handle)
-//
+// Its methods (ServerCodec and ClientCodec) return values that implement RpcCodecBuffered.
 var GoRpc goRpc
 
 func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
@@ -230,3 +176,5 @@ func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
 func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
 	return &goRpcCodec{newRPCCodec(conn, h)}
 }
+
+var _ RpcCodecBuffered = (*rpcCodec)(nil) // ensure *rpcCodec implements RpcCodecBuffered
diff --git a/vendor/github.com/ugorji/go/codec/simple.go b/vendor/github.com/ugorji/go/codec/simple.go
index f1e181ef3..fdc457571 100644
--- a/vendor/github.com/ugorji/go/codec/simple.go
+++ b/vendor/github.com/ugorji/go/codec/simple.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 package codec
@@ -6,7 +6,6 @@ package codec
 import (
 	"math"
 	"reflect"
-	"time"
 )
 
 const (
@@ -21,8 +20,6 @@ const (
 	simpleVdPosInt = 8
 	simpleVdNegInt = 12
 
-	simpleVdTime = 24
-
 	// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
 	simpleVdString    = 216
 	simpleVdByteArray = 224
@@ -33,15 +30,11 @@ const (
 
 type simpleEncDriver struct {
 	noBuiltInTypes
-	// encNoSeparator
+	encNoSeparator
 	e *Encoder
 	h *SimpleHandle
 	w encWriter
 	b [8]byte
-	// c containerState
-	encDriverTrackContainerWriter
-	// encDriverNoopContainerWriter
-	_ [2]uint64 // padding
 }
 
 func (e *simpleEncDriver) EncodeNil() {
@@ -49,10 +42,6 @@ func (e *simpleEncDriver) EncodeNil() {
 }
 
 func (e *simpleEncDriver) EncodeBool(b bool) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && !b {
-		e.EncodeNil()
-		return
-	}
 	if b {
 		e.w.writen1(simpleVdTrue)
 	} else {
@@ -61,19 +50,11 @@ func (e *simpleEncDriver) EncodeBool(b bool) {
 }
 
 func (e *simpleEncDriver) EncodeFloat32(f float32) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
-		e.EncodeNil()
-		return
-	}
 	e.w.writen1(simpleVdFloat32)
 	bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
 }
 
 func (e *simpleEncDriver) EncodeFloat64(f float64) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
-		e.EncodeNil()
-		return
-	}
 	e.w.writen1(simpleVdFloat64)
 	bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f))
 }
@@ -91,10 +72,6 @@ func (e *simpleEncDriver) EncodeUint(v uint64) {
 }
 
 func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == 0 {
-		e.EncodeNil()
-		return
-	}
 	if v <= math.MaxUint8 {
 		e.w.writen2(bd, uint8(v))
 	} else if v <= math.MaxUint16 {
@@ -147,55 +124,28 @@ func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) {
 	e.w.writen1(xtag)
 }
 
-func (e *simpleEncDriver) WriteArrayStart(length int) {
-	e.c = containerArrayStart
+func (e *simpleEncDriver) EncodeArrayStart(length int) {
 	e.encLen(simpleVdArray, length)
 }
 
-func (e *simpleEncDriver) WriteMapStart(length int) {
-	e.c = containerMapStart
+func (e *simpleEncDriver) EncodeMapStart(length int) {
 	e.encLen(simpleVdMap, length)
 }
 
 func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
-	if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
-		e.EncodeNil()
-		return
-	}
 	e.encLen(simpleVdString, len(v))
 	e.w.writestr(v)
 }
 
-// func (e *simpleEncDriver) EncodeSymbol(v string) {
-// 	e.EncodeString(cUTF8, v)
-// }
+func (e *simpleEncDriver) EncodeSymbol(v string) {
+	e.EncodeString(c_UTF8, v)
+}
 
 func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
-	if v == nil {
-		e.EncodeNil()
-		return
-	}
 	e.encLen(simpleVdByteArray, len(v))
 	e.w.writeb(v)
 }
 
-func (e *simpleEncDriver) EncodeTime(t time.Time) {
-	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && t.IsZero() {
-	if t.IsZero() {
-		e.EncodeNil()
-		return
-	}
-	v, err := t.MarshalBinary()
-	if err != nil {
-		e.e.errorv(err)
-		return
-	}
-	// time.Time marshalbinary takes about 14 bytes.
-	e.w.writen2(simpleVdTime, uint8(len(v)))
-	e.w.writeb(v)
-}
-
 //------------------------------------
 
 type simpleDecDriver struct {
@@ -204,13 +154,11 @@ type simpleDecDriver struct {
 	r      decReader
 	bdRead bool
 	bd     byte
-	br     bool // a bytes reader?
-	c      containerState
-	// b      [scratchByteArrayLen]byte
+	br     bool // bytes reader
 	noBuiltInTypes
-	// noStreamingCodec
-	decDriverNoopContainerReader
-	_ [3]uint64 // padding
+	noStreamingCodec
+	decNoSeparator
+	b [scratchByteArrayLen]byte
 }
 
 func (d *simpleDecDriver) readNextBd() {
@@ -226,30 +174,23 @@ func (d *simpleDecDriver) uncacheRead() {
 }
 
 func (d *simpleDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch d.bd {
-	case simpleVdNil:
+	if d.bd == simpleVdNil {
 		return valueTypeNil
-	case simpleVdByteArray, simpleVdByteArray + 1,
-		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
+	} else if d.bd == simpleVdByteArray || d.bd == simpleVdByteArray+1 ||
+		d.bd == simpleVdByteArray+2 || d.bd == simpleVdByteArray+3 || d.bd == simpleVdByteArray+4 {
 		return valueTypeBytes
-	case simpleVdString, simpleVdString + 1,
-		simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
+	} else if d.bd == simpleVdString || d.bd == simpleVdString+1 ||
+		d.bd == simpleVdString+2 || d.bd == simpleVdString+3 || d.bd == simpleVdString+4 {
 		return valueTypeString
-	case simpleVdArray, simpleVdArray + 1,
-		simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
+	} else if d.bd == simpleVdArray || d.bd == simpleVdArray+1 ||
+		d.bd == simpleVdArray+2 || d.bd == simpleVdArray+3 || d.bd == simpleVdArray+4 {
 		return valueTypeArray
-	case simpleVdMap, simpleVdMap + 1,
-		simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
+	} else if d.bd == simpleVdMap || d.bd == simpleVdMap+1 ||
+		d.bd == simpleVdMap+2 || d.bd == simpleVdMap+3 || d.bd == simpleVdMap+4 {
 		return valueTypeMap
-		// case simpleVdTime:
-		// 	return valueTypeTime
+	} else {
+		// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
 	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
 	return valueTypeUnset
 }
 
@@ -290,7 +231,7 @@ func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
 		ui = uint64(bigen.Uint64(d.r.readx(8)))
 		neg = true
 	default:
-		d.d.errorf("integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
+		d.d.errorf("decIntAny: Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
 		return
 	}
 	// don't do this check, because callers may only want the unsigned value.
@@ -301,27 +242,39 @@ func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
 	return
 }
 
-func (d *simpleDecDriver) DecodeInt64() (i int64) {
+func (d *simpleDecDriver) DecodeInt(bitsize uint8) (i int64) {
 	ui, neg := d.decCheckInteger()
-	i = chkOvf.SignedIntV(ui)
+	i, overflow := chkOvf.SignedInt(ui)
+	if overflow {
+		d.d.errorf("simple: overflow converting %v to signed integer", ui)
+		return
+	}
 	if neg {
 		i = -i
 	}
+	if chkOvf.Int(i, bitsize) {
+		d.d.errorf("simple: overflow integer: %v", i)
+		return
+	}
 	d.bdRead = false
 	return
 }
 
-func (d *simpleDecDriver) DecodeUint64() (ui uint64) {
+func (d *simpleDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
 	ui, neg := d.decCheckInteger()
 	if neg {
-		d.d.errorf("assigning negative signed value to unsigned type")
+		d.d.errorf("Assigning negative signed value to unsigned type")
+		return
+	}
+	if chkOvf.Uint(ui, bitsize) {
+		d.d.errorf("simple: overflow integer: %v", ui)
 		return
 	}
 	d.bdRead = false
 	return
 }
 
-func (d *simpleDecDriver) DecodeFloat64() (f float64) {
+func (d *simpleDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -331,12 +284,16 @@ func (d *simpleDecDriver) DecodeFloat64() (f float64) {
 		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
 	} else {
 		if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
-			f = float64(d.DecodeInt64())
+			f = float64(d.DecodeInt(64))
 		} else {
-			d.d.errorf("float only valid from float32/64: Invalid descriptor: %v", d.bd)
+			d.d.errorf("Float only valid from float32/64: Invalid descriptor: %v", d.bd)
 			return
 		}
 	}
+	if chkOverflow32 && chkOvf.Float32(f) {
+		d.d.errorf("msgpack: float32 overflow: %v", f)
+		return
+	}
 	d.bdRead = false
 	return
 }
@@ -350,7 +307,7 @@ func (d *simpleDecDriver) DecodeBool() (b bool) {
 		b = true
 	} else if d.bd == simpleVdFalse {
 	} else {
-		d.d.errorf("cannot decode bool - %s: %x", msgBadDesc, d.bd)
+		d.d.errorf("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd)
 		return
 	}
 	d.bdRead = false
@@ -358,43 +315,15 @@ func (d *simpleDecDriver) DecodeBool() (b bool) {
 }
 
 func (d *simpleDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	d.bdRead = false
-	d.c = containerMapStart
 	return d.decLen()
 }
 
 func (d *simpleDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
 	d.bdRead = false
-	d.c = containerArrayStart
 	return d.decLen()
 }
 
-func (d *simpleDecDriver) ReadArrayElem() {
-	d.c = containerArrayElem
-}
-
-func (d *simpleDecDriver) ReadArrayEnd() {
-	d.c = containerArrayEnd
-}
-
-func (d *simpleDecDriver) ReadMapElemKey() {
-	d.c = containerMapKey
-}
-
-func (d *simpleDecDriver) ReadMapElemValue() {
-	d.c = containerMapValue
-}
-
-func (d *simpleDecDriver) ReadMapEnd() {
-	d.c = containerMapEnd
-}
-
 func (d *simpleDecDriver) decLen() int {
 	switch d.bd % 8 {
 	case 0:
@@ -406,31 +335,27 @@ func (d *simpleDecDriver) decLen() int {
 	case 3:
 		ui := uint64(bigen.Uint32(d.r.readx(4)))
 		if chkOvf.Uint(ui, intBitsize) {
-			d.d.errorf("overflow integer: %v", ui)
+			d.d.errorf("simple: overflow integer: %v", ui)
 			return 0
 		}
 		return int(ui)
 	case 4:
 		ui := bigen.Uint64(d.r.readx(8))
 		if chkOvf.Uint(ui, intBitsize) {
-			d.d.errorf("overflow integer: %v", ui)
+			d.d.errorf("simple: overflow integer: %v", ui)
 			return 0
 		}
 		return int(ui)
 	}
-	d.d.errorf("cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8)
+	d.d.errorf("decLen: Cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8)
 	return -1
 }
 
 func (d *simpleDecDriver) DecodeString() (s string) {
-	return string(d.DecodeBytes(d.d.b[:], true))
+	return string(d.DecodeBytes(d.b[:], true, true))
 }
 
-func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
-	return d.DecodeBytes(d.d.b[:], true)
-}
-
-func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+func (d *simpleDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) {
 	if !d.bdRead {
 		d.readNextBd()
 	}
@@ -438,51 +363,21 @@ func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 		d.bdRead = false
 		return
 	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.bd >= simpleVdArray && d.bd <= simpleVdMap+4 {
-		if len(bs) == 0 && zerocopy {
-			bs = d.d.b[:]
-		}
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
-
 	clen := d.decLen()
 	d.bdRead = false
 	if zerocopy {
 		if d.br {
 			return d.r.readx(clen)
 		} else if len(bs) == 0 {
-			bs = d.d.b[:]
+			bs = d.b[:]
 		}
 	}
 	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
 }
 
-func (d *simpleDecDriver) DecodeTime() (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == simpleVdNil {
-		d.bdRead = false
-		return
-	}
-	if d.bd != simpleVdTime {
-		d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd)
-		return
-	}
-	d.bdRead = false
-	clen := int(d.r.readn1())
-	b := d.r.readx(clen)
-	if err := (&t).UnmarshalBinary(b); err != nil {
-		d.d.errorv(err)
-	}
-	return
-}
-
 func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
 	if xtag > 0xff {
-		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
+		d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
 		return
 	}
 	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
@@ -506,15 +401,14 @@ func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs [
 		l := d.decLen()
 		xtag = d.r.readn1()
 		if verifyTag && xtag != tag {
-			d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag)
+			d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", xtag, tag)
 			return
 		}
 		xbs = d.r.readx(l)
-	case simpleVdByteArray, simpleVdByteArray + 1,
-		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
-		xbs = d.DecodeBytes(nil, true)
+	case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
+		xbs = d.DecodeBytes(nil, false, true)
 	default:
-		d.d.errorf("ext - %s - expecting extensions/bytearray, got: 0x%x", msgBadDesc, d.bd)
+		d.d.errorf("Invalid d.bd for extensions (Expecting extensions or byte array). Got: 0x%x", d.bd)
 		return
 	}
 	d.bdRead = false
@@ -526,7 +420,7 @@ func (d *simpleDecDriver) DecodeNaked() {
 		d.readNextBd()
 	}
 
-	n := d.d.n
+	n := &d.d.n
 	var decodeFurther bool
 
 	switch d.bd {
@@ -541,45 +435,39 @@ func (d *simpleDecDriver) DecodeNaked() {
 	case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
 		if d.h.SignedInteger {
 			n.v = valueTypeInt
-			n.i = d.DecodeInt64()
+			n.i = d.DecodeInt(64)
 		} else {
 			n.v = valueTypeUint
-			n.u = d.DecodeUint64()
+			n.u = d.DecodeUint(64)
 		}
 	case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
 		n.v = valueTypeInt
-		n.i = d.DecodeInt64()
+		n.i = d.DecodeInt(64)
 	case simpleVdFloat32:
 		n.v = valueTypeFloat
-		n.f = d.DecodeFloat64()
+		n.f = d.DecodeFloat(true)
 	case simpleVdFloat64:
 		n.v = valueTypeFloat
-		n.f = d.DecodeFloat64()
-	case simpleVdTime:
-		n.v = valueTypeTime
-		n.t = d.DecodeTime()
-	case simpleVdString, simpleVdString + 1,
-		simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
+		n.f = d.DecodeFloat(false)
+	case simpleVdString, simpleVdString + 1, simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
 		n.v = valueTypeString
 		n.s = d.DecodeString()
-	case simpleVdByteArray, simpleVdByteArray + 1,
-		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
+	case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
 		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
+		n.l = d.DecodeBytes(nil, false, false)
 	case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
 		n.v = valueTypeExt
 		l := d.decLen()
 		n.u = uint64(d.r.readn1())
 		n.l = d.r.readx(l)
-	case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
-		simpleVdArray + 3, simpleVdArray + 4:
+	case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
 		n.v = valueTypeArray
 		decodeFurther = true
 	case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
 		n.v = valueTypeMap
 		decodeFurther = true
 	default:
-		d.d.errorf("cannot infer value - %s 0x%x", msgBadDesc, d.bd)
+		d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
 	}
 
 	if !decodeFurther {
@@ -598,7 +486,7 @@ func (d *simpleDecDriver) DecodeNaked() {
 //   - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte).
 //     There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
 //   - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
-//   - Length of containers (strings, bytes, array, map, extensions)
+//   - Lenght of containers (strings, bytes, array, map, extensions)
 //     are encoded in 0, 1, 2, 4 or 8 bytes.
 //     Zero-length containers have no length encoded.
 //     For others, the number of bytes is given by pow(2, bd%3)
@@ -606,45 +494,31 @@ func (d *simpleDecDriver) DecodeNaked() {
 //   - arrays are encoded as [bd] [length] [value]...
 //   - extensions are encoded as [bd] [length] [tag] [byte]...
 //   - strings/bytearrays are encoded as [bd] [length] [byte]...
-//   - time.Time are encoded as [bd] [length] [byte]...
 //
 // The full spec will be published soon.
 type SimpleHandle struct {
 	BasicHandle
 	binaryEncodingType
-	noElemSeparators
-	// EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil
-	EncZeroValuesAsNil bool
-
-	// _ [1]uint64 // padding
 }
 
-// Name returns the name of the handle: simple
-func (h *SimpleHandle) Name() string { return "simple" }
-
-// SetBytesExt sets an extension
 func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
+	return h.SetExt(rt, tag, &setExtWrapper{b: ext})
 }
 
-func (h *SimpleHandle) hasElemSeparators() bool { return true } // as it implements Write(Map|Array)XXX
-
 func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver {
 	return &simpleEncDriver{e: e, w: e.w, h: h}
 }
 
 func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver {
-	return &simpleDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+	return &simpleDecDriver{d: d, r: d.r, h: h, br: d.bytes}
 }
 
 func (e *simpleEncDriver) reset() {
-	e.c = 0
 	e.w = e.e.w
 }
 
 func (d *simpleDecDriver) reset() {
-	d.c = 0
-	d.r, d.br = d.d.r, d.d.bytes
+	d.r = d.d.r
 	d.bd, d.bdRead = 0, false
 }
 
diff --git a/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json b/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
new file mode 100644
index 000000000..902858671
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
@@ -0,0 +1,639 @@
+[
+  {
+    "cbor": "AA==",
+    "hex": "00",
+    "roundtrip": true,
+    "decoded": 0
+  },
+  {
+    "cbor": "AQ==",
+    "hex": "01",
+    "roundtrip": true,
+    "decoded": 1
+  },
+  {
+    "cbor": "Cg==",
+    "hex": "0a",
+    "roundtrip": true,
+    "decoded": 10
+  },
+  {
+    "cbor": "Fw==",
+    "hex": "17",
+    "roundtrip": true,
+    "decoded": 23
+  },
+  {
+    "cbor": "GBg=",
+    "hex": "1818",
+    "roundtrip": true,
+    "decoded": 24
+  },
+  {
+    "cbor": "GBk=",
+    "hex": "1819",
+    "roundtrip": true,
+    "decoded": 25
+  },
+  {
+    "cbor": "GGQ=",
+    "hex": "1864",
+    "roundtrip": true,
+    "decoded": 100
+  },
+  {
+    "cbor": "GQPo",
+    "hex": "1903e8",
+    "roundtrip": true,
+    "decoded": 1000
+  },
+  {
+    "cbor": "GgAPQkA=",
+    "hex": "1a000f4240",
+    "roundtrip": true,
+    "decoded": 1000000
+  },
+  {
+    "cbor": "GwAAAOjUpRAA",
+    "hex": "1b000000e8d4a51000",
+    "roundtrip": true,
+    "decoded": 1000000000000
+  },
+  {
+    "cbor": "G///////////",
+    "hex": "1bffffffffffffffff",
+    "roundtrip": true,
+    "decoded": 18446744073709551615
+  },
+  {
+    "cbor": "wkkBAAAAAAAAAAA=",
+    "hex": "c249010000000000000000",
+    "roundtrip": true,
+    "decoded": 18446744073709551616
+  },
+  {
+    "cbor": "O///////////",
+    "hex": "3bffffffffffffffff",
+    "roundtrip": true,
+    "decoded": -18446744073709551616,
+    "skip": true
+  },
+  {
+    "cbor": "w0kBAAAAAAAAAAA=",
+    "hex": "c349010000000000000000",
+    "roundtrip": true,
+    "decoded": -18446744073709551617
+  },
+  {
+    "cbor": "IA==",
+    "hex": "20",
+    "roundtrip": true,
+    "decoded": -1
+  },
+  {
+    "cbor": "KQ==",
+    "hex": "29",
+    "roundtrip": true,
+    "decoded": -10
+  },
+  {
+    "cbor": "OGM=",
+    "hex": "3863",
+    "roundtrip": true,
+    "decoded": -100
+  },
+  {
+    "cbor": "OQPn",
+    "hex": "3903e7",
+    "roundtrip": true,
+    "decoded": -1000
+  },
+  {
+    "cbor": "+QAA",
+    "hex": "f90000",
+    "roundtrip": true,
+    "decoded": 0.0
+  },
+  {
+    "cbor": "+YAA",
+    "hex": "f98000",
+    "roundtrip": true,
+    "decoded": -0.0
+  },
+  {
+    "cbor": "+TwA",
+    "hex": "f93c00",
+    "roundtrip": true,
+    "decoded": 1.0
+  },
+  {
+    "cbor": "+z/xmZmZmZma",
+    "hex": "fb3ff199999999999a",
+    "roundtrip": true,
+    "decoded": 1.1
+  },
+  {
+    "cbor": "+T4A",
+    "hex": "f93e00",
+    "roundtrip": true,
+    "decoded": 1.5
+  },
+  {
+    "cbor": "+Xv/",
+    "hex": "f97bff",
+    "roundtrip": true,
+    "decoded": 65504.0
+  },
+  {
+    "cbor": "+kfDUAA=",
+    "hex": "fa47c35000",
+    "roundtrip": true,
+    "decoded": 100000.0
+  },
+  {
+    "cbor": "+n9///8=",
+    "hex": "fa7f7fffff",
+    "roundtrip": true,
+    "decoded": 3.4028234663852886e+38
+  },
+  {
+    "cbor": "+3435DyIAHWc",
+    "hex": "fb7e37e43c8800759c",
+    "roundtrip": true,
+    "decoded": 1.0e+300
+  },
+  {
+    "cbor": "+QAB",
+    "hex": "f90001",
+    "roundtrip": true,
+    "decoded": 5.960464477539063e-08
+  },
+  {
+    "cbor": "+QQA",
+    "hex": "f90400",
+    "roundtrip": true,
+    "decoded": 6.103515625e-05
+  },
+  {
+    "cbor": "+cQA",
+    "hex": "f9c400",
+    "roundtrip": true,
+    "decoded": -4.0
+  },
+  {
+    "cbor": "+8AQZmZmZmZm",
+    "hex": "fbc010666666666666",
+    "roundtrip": true,
+    "decoded": -4.1
+  },
+  {
+    "cbor": "+XwA",
+    "hex": "f97c00",
+    "roundtrip": true,
+    "diagnostic": "Infinity"
+  },
+  {
+    "cbor": "+X4A",
+    "hex": "f97e00",
+    "roundtrip": true,
+    "diagnostic": "NaN"
+  },
+  {
+    "cbor": "+fwA",
+    "hex": "f9fc00",
+    "roundtrip": true,
+    "diagnostic": "-Infinity"
+  },
+  {
+    "cbor": "+n+AAAA=",
+    "hex": "fa7f800000",
+    "roundtrip": false,
+    "diagnostic": "Infinity"
+  },
+  {
+    "cbor": "+n/AAAA=",
+    "hex": "fa7fc00000",
+    "roundtrip": false,
+    "diagnostic": "NaN"
+  },
+  {
+    "cbor": "+v+AAAA=",
+    "hex": "faff800000",
+    "roundtrip": false,
+    "diagnostic": "-Infinity"
+  },
+  {
+    "cbor": "+3/wAAAAAAAA",
+    "hex": "fb7ff0000000000000",
+    "roundtrip": false,
+    "diagnostic": "Infinity"
+  },
+  {
+    "cbor": "+3/4AAAAAAAA",
+    "hex": "fb7ff8000000000000",
+    "roundtrip": false,
+    "diagnostic": "NaN"
+  },
+  {
+    "cbor": "+//wAAAAAAAA",
+    "hex": "fbfff0000000000000",
+    "roundtrip": false,
+    "diagnostic": "-Infinity"
+  },
+  {
+    "cbor": "9A==",
+    "hex": "f4",
+    "roundtrip": true,
+    "decoded": false
+  },
+  {
+    "cbor": "9Q==",
+    "hex": "f5",
+    "roundtrip": true,
+    "decoded": true
+  },
+  {
+    "cbor": "9g==",
+    "hex": "f6",
+    "roundtrip": true,
+    "decoded": null
+  },
+  {
+    "cbor": "9w==",
+    "hex": "f7",
+    "roundtrip": true,
+    "diagnostic": "undefined"
+  },
+  {
+    "cbor": "8A==",
+    "hex": "f0",
+    "roundtrip": true,
+    "diagnostic": "simple(16)"
+  },
+  {
+    "cbor": "+Bg=",
+    "hex": "f818",
+    "roundtrip": true,
+    "diagnostic": "simple(24)"
+  },
+  {
+    "cbor": "+P8=",
+    "hex": "f8ff",
+    "roundtrip": true,
+    "diagnostic": "simple(255)"
+  },
+  {
+    "cbor": "wHQyMDEzLTAzLTIxVDIwOjA0OjAwWg==",
+    "hex": "c074323031332d30332d32315432303a30343a30305a",
+    "roundtrip": true,
+    "diagnostic": "0(\"2013-03-21T20:04:00Z\")"
+  },
+  {
+    "cbor": "wRpRS2ew",
+    "hex": "c11a514b67b0",
+    "roundtrip": true,
+    "diagnostic": "1(1363896240)"
+  },
+  {
+    "cbor": "wftB1FLZ7CAAAA==",
+    "hex": "c1fb41d452d9ec200000",
+    "roundtrip": true,
+    "diagnostic": "1(1363896240.5)"
+  },
+  {
+    "cbor": "10QBAgME",
+    "hex": "d74401020304",
+    "roundtrip": true,
+    "diagnostic": "23(h'01020304')"
+  },
+  {
+    "cbor": "2BhFZElFVEY=",
+    "hex": "d818456449455446",
+    "roundtrip": true,
+    "diagnostic": "24(h'6449455446')"
+  },
+  {
+    "cbor": "2CB2aHR0cDovL3d3dy5leGFtcGxlLmNvbQ==",
+    "hex": "d82076687474703a2f2f7777772e6578616d706c652e636f6d",
+    "roundtrip": true,
+    "diagnostic": "32(\"http://www.example.com\")"
+  },
+  {
+    "cbor": "QA==",
+    "hex": "40",
+    "roundtrip": true,
+    "diagnostic": "h''"
+  },
+  {
+    "cbor": "RAECAwQ=",
+    "hex": "4401020304",
+    "roundtrip": true,
+    "diagnostic": "h'01020304'"
+  },
+  {
+    "cbor": "YA==",
+    "hex": "60",
+    "roundtrip": true,
+    "decoded": ""
+  },
+  {
+    "cbor": "YWE=",
+    "hex": "6161",
+    "roundtrip": true,
+    "decoded": "a"
+  },
+  {
+    "cbor": "ZElFVEY=",
+    "hex": "6449455446",
+    "roundtrip": true,
+    "decoded": "IETF"
+  },
+  {
+    "cbor": "YiJc",
+    "hex": "62225c",
+    "roundtrip": true,
+    "decoded": "\"\\"
+  },
+  {
+    "cbor": "YsO8",
+    "hex": "62c3bc",
+    "roundtrip": true,
+    "decoded": "ü"
+  },
+  {
+    "cbor": "Y+awtA==",
+    "hex": "63e6b0b4",
+    "roundtrip": true,
+    "decoded": "水"
+  },
+  {
+    "cbor": "ZPCQhZE=",
+    "hex": "64f0908591",
+    "roundtrip": true,
+    "decoded": "𐅑"
+  },
+  {
+    "cbor": "gA==",
+    "hex": "80",
+    "roundtrip": true,
+    "decoded": [
+
+    ]
+  },
+  {
+    "cbor": "gwECAw==",
+    "hex": "83010203",
+    "roundtrip": true,
+    "decoded": [
+      1,
+      2,
+      3
+    ]
+  },
+  {
+    "cbor": "gwGCAgOCBAU=",
+    "hex": "8301820203820405",
+    "roundtrip": true,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "mBkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgYGBk=",
+    "hex": "98190102030405060708090a0b0c0d0e0f101112131415161718181819",
+    "roundtrip": true,
+    "decoded": [
+      1,
+      2,
+      3,
+      4,
+      5,
+      6,
+      7,
+      8,
+      9,
+      10,
+      11,
+      12,
+      13,
+      14,
+      15,
+      16,
+      17,
+      18,
+      19,
+      20,
+      21,
+      22,
+      23,
+      24,
+      25
+    ]
+  },
+  {
+    "cbor": "oA==",
+    "hex": "a0",
+    "roundtrip": true,
+    "decoded": {
+    }
+  },
+  {
+    "cbor": "ogECAwQ=",
+    "hex": "a201020304",
+    "roundtrip": true,
+    "skip": true,
+    "diagnostic": "{1: 2, 3: 4}"
+  },
+  {
+    "cbor": "omFhAWFiggID",
+    "hex": "a26161016162820203",
+    "roundtrip": true,
+    "decoded": {
+      "a": 1,
+      "b": [
+        2,
+        3
+      ]
+    }
+  },
+  {
+    "cbor": "gmFhoWFiYWM=",
+    "hex": "826161a161626163",
+    "roundtrip": true,
+    "decoded": [
+      "a",
+      {
+        "b": "c"
+      }
+    ]
+  },
+  {
+    "cbor": "pWFhYUFhYmFCYWNhQ2FkYURhZWFF",
+    "hex": "a56161614161626142616361436164614461656145",
+    "roundtrip": true,
+    "decoded": {
+      "a": "A",
+      "b": "B",
+      "c": "C",
+      "d": "D",
+      "e": "E"
+    }
+  },
+  {
+    "cbor": "X0IBAkMDBAX/",
+    "hex": "5f42010243030405ff",
+    "roundtrip": false,
+    "skip": true,
+    "diagnostic": "(_ h'0102', h'030405')"
+  },
+  {
+    "cbor": "f2VzdHJlYWRtaW5n/w==",
+    "hex": "7f657374726561646d696e67ff",
+    "roundtrip": false,
+    "decoded": "streaming"
+  },
+  {
+    "cbor": "n/8=",
+    "hex": "9fff",
+    "roundtrip": false,
+    "decoded": [
+
+    ]
+  },
+  {
+    "cbor": "nwGCAgOfBAX//w==",
+    "hex": "9f018202039f0405ffff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "nwGCAgOCBAX/",
+    "hex": "9f01820203820405ff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "gwGCAgOfBAX/",
+    "hex": "83018202039f0405ff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "gwGfAgP/ggQF",
+    "hex": "83019f0203ff820405",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "nwECAwQFBgcICQoLDA0ODxAREhMUFRYXGBgYGf8=",
+    "hex": "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      2,
+      3,
+      4,
+      5,
+      6,
+      7,
+      8,
+      9,
+      10,
+      11,
+      12,
+      13,
+      14,
+      15,
+      16,
+      17,
+      18,
+      19,
+      20,
+      21,
+      22,
+      23,
+      24,
+      25
+    ]
+  },
+  {
+    "cbor": "v2FhAWFinwID//8=",
+    "hex": "bf61610161629f0203ffff",
+    "roundtrip": false,
+    "decoded": {
+      "a": 1,
+      "b": [
+        2,
+        3
+      ]
+    }
+  },
+  {
+    "cbor": "gmFhv2FiYWP/",
+    "hex": "826161bf61626163ff",
+    "roundtrip": false,
+    "decoded": [
+      "a",
+      {
+        "b": "c"
+      }
+    ]
+  },
+  {
+    "cbor": "v2NGdW71Y0FtdCH/",
+    "hex": "bf6346756ef563416d7421ff",
+    "roundtrip": false,
+    "decoded": {
+      "Fun": true,
+      "Amt": -2
+    }
+  }
+]
diff --git a/vendor/github.com/ugorji/go/codec/test.py b/vendor/github.com/ugorji/go/codec/test.py
new file mode 100755
index 000000000..f983d9d9e
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/test.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+
+# This will create golden files in a directory passed to it.
+# A Test calls this internally to create the golden files
+# So it can process them (so we don't have to checkin the files).
+
+# Ensure msgpack-python and cbor are installed first, using:
+#   sudo apt-get install python-dev
+#   sudo apt-get install python-pip
+#   pip install --user msgpack-python msgpack-rpc-python cbor
+
+# Ensure all "string" keys are utf strings (else encoded as bytes)
+
+import cbor, msgpack, msgpackrpc, sys, os, threading
+
+def get_test_data_list():
+    # get list with all primitive types, and a combo type
+    l0 = [ 
+        -8,
+         -1616,
+         -32323232,
+         -6464646464646464,
+         192,
+         1616,
+         32323232,
+         6464646464646464,
+         192,
+         -3232.0,
+         -6464646464.0,
+         3232.0,
+         6464.0,
+         6464646464.0,
+         False,
+         True,
+         u"null",
+         None,
+         u"some&day>some<day",
+         1328176922000002000,
+         u"",
+         -2206187877999998000,
+         u"bytestring",
+         270,
+         u"none",
+        -2013855847999995777,
+         #-6795364578871345152,
+         ]
+    l1 = [
+        { "true": True,
+          "false": False },
+        { "true": u"True",
+          "false": False,
+          "uint16(1616)": 1616 },
+        { "list": [1616, 32323232, True, -3232.0, {"TRUE":True, "FALSE":False}, [True, False] ],
+          "int32":32323232, "bool": True, 
+          "LONG STRING": u"123456789012345678901234567890123456789012345678901234567890",
+          "SHORT STRING": u"1234567890" },
+        { True: "true", 138: False, "false": 200 }
+        ]
+    
+    l = []
+    l.extend(l0)
+    l.append(l0)
+    l.append(1)
+    l.extend(l1)
+    return l
+
+def build_test_data(destdir):
+    l = get_test_data_list()
+    for i in range(len(l)):
+        # packer = msgpack.Packer()
+        serialized = msgpack.dumps(l[i])
+        f = open(os.path.join(destdir, str(i) + '.msgpack.golden'), 'wb')
+        f.write(serialized)
+        f.close()
+        serialized = cbor.dumps(l[i])
+        f = open(os.path.join(destdir, str(i) + '.cbor.golden'), 'wb')
+        f.write(serialized)
+        f.close()
+
+def doRpcServer(port, stopTimeSec):
+    class EchoHandler(object):
+        def Echo123(self, msg1, msg2, msg3):
+            return ("1:%s 2:%s 3:%s" % (msg1, msg2, msg3))
+        def EchoStruct(self, msg):
+            return ("%s" % msg)
+    
+    addr = msgpackrpc.Address('localhost', port)
+    server = msgpackrpc.Server(EchoHandler())
+    server.listen(addr)
+    # run thread to stop it after stopTimeSec seconds if > 0
+    if stopTimeSec > 0:
+        def myStopRpcServer():
+            server.stop()
+        t = threading.Timer(stopTimeSec, myStopRpcServer)
+        t.start()
+    server.start()
+
+def doRpcClientToPythonSvc(port):
+    address = msgpackrpc.Address('localhost', port)
+    client = msgpackrpc.Client(address, unpack_encoding='utf-8')
+    print client.call("Echo123", "A1", "B2", "C3")
+    print client.call("EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
+   
+def doRpcClientToGoSvc(port):
+    # print ">>>> port: ", port, " <<<<<"
+    address = msgpackrpc.Address('localhost', port)
+    client = msgpackrpc.Client(address, unpack_encoding='utf-8')
+    print client.call("TestRpcInt.Echo123", ["A1", "B2", "C3"])
+    print client.call("TestRpcInt.EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
+
+def doMain(args):
+    if len(args) == 2 and args[0] == "testdata":
+        build_test_data(args[1])
+    elif len(args) == 3 and args[0] == "rpc-server":
+        doRpcServer(int(args[1]), int(args[2]))
+    elif len(args) == 2 and args[0] == "rpc-client-python-service":
+        doRpcClientToPythonSvc(int(args[1]))
+    elif len(args) == 2 and args[0] == "rpc-client-go-service":
+        doRpcClientToGoSvc(int(args[1]))
+    else:
+        print("Usage: test.py " + 
+              "[testdata|rpc-server|rpc-client-python-service|rpc-client-go-service] ...")
+    
+if __name__ == "__main__":
+    doMain(sys.argv[1:])
+
diff --git a/vendor/github.com/ugorji/go/codec/tests.sh b/vendor/github.com/ugorji/go/codec/tests.sh
new file mode 100755
index 000000000..fc9f5dee3
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/tests.sh
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+# Run all the different permutations of all the tests.
+# This helps ensure that nothing gets broken.
+
+_run() {
+    # 1. VARIATIONS: regular (t), canonical (c), IO R/W (i),
+    #                binc-nosymbols (n), struct2array (s), intern string (e),
+    #                json-indent (d), circular (l)
+    # 2. MODE: reflection (r), external (x), codecgen (g), unsafe (u), notfastpath (f)
+    # 3. OPTIONS: verbose (v), reset (z), must (m),
+    # 
+    # Use combinations of mode to get exactly what you want,
+    # and then pass the variations you need.
+
+    ztags=""
+    zargs=""
+    local OPTIND 
+    OPTIND=1
+    # "_xurtcinsvgzmefdl" ===  "_cdefgilmnrtsuvxz"
+    while getopts "_cdefgilmnrtsuvwxz" flag
+    do
+        case "x$flag" in 
+            'xr')  ;;
+            'xf') ztags="$ztags notfastpath" ;;
+            'xg') ztags="$ztags codecgen" ;;
+            'xx') ztags="$ztags x" ;;
+            'xu') ztags="$ztags unsafe" ;;
+            'xv') zargs="$zargs -tv" ;;
+            'xz') zargs="$zargs -tr" ;;
+            'xm') zargs="$zargs -tm" ;;
+            'xl') zargs="$zargs -tl" ;;
+            'xw') zargs="$zargs -tx=10" ;;
+            *) ;;
+        esac
+    done
+    # shift $((OPTIND-1))
+    printf '............. TAGS: %s .............\n' "$ztags"
+    # echo ">>>>>>> TAGS: $ztags"
+    
+    OPTIND=1
+    while getopts "_cdefgilmnrtsuvwxz" flag
+    do
+        case "x$flag" in 
+            'xt') printf ">>>>>>> REGULAR    : "; go test "-tags=$ztags" $zargs ; sleep 2 ;;
+            'xc') printf ">>>>>>> CANONICAL  : "; go test "-tags=$ztags" $zargs -tc; sleep 2 ;;
+            'xi') printf ">>>>>>> I/O        : "; go test "-tags=$ztags" $zargs -ti; sleep 2 ;;
+            'xn') printf ">>>>>>> NO_SYMBOLS : "; go test "-tags=$ztags" -run=Binc $zargs -tn; sleep 2 ;;
+            'xs') printf ">>>>>>> TO_ARRAY   : "; go test "-tags=$ztags" $zargs -ts; sleep 2 ;;
+            'xe') printf ">>>>>>> INTERN     : "; go test "-tags=$ztags" $zargs -te; sleep 2 ;;
+            'xd') printf ">>>>>>> INDENT     : ";
+                  go test "-tags=$ztags" -run=JsonCodecsTable -td=-1 $zargs;
+                  go test "-tags=$ztags" -run=JsonCodecsTable -td=8 $zargs;
+                  sleep 2 ;;
+            *) ;;
+        esac
+    done
+    shift $((OPTIND-1))
+
+    OPTIND=1
+}
+
+# echo ">>>>>>> RUNNING VARIATIONS OF TESTS"    
+if [[ "x$@" = "x"  || "x$@" = "x-A" ]]; then
+    # All: r, x, g, gu
+    _run "-_tcinsed_ml"  # regular
+    _run "-_tcinsed_ml_z" # regular with reset
+    _run "-w_tcinsed_ml"  # regular with max init len
+    _run "-_tcinsed_ml_f" # regular with no fastpath (notfastpath)
+    _run "-x_tcinsed_ml" # external
+    _run "-gx_tcinsed_ml" # codecgen: requires external
+    _run "-gxu_tcinsed_ml" # codecgen + unsafe
+elif [[ "x$@" = "x-Z" ]]; then
+    # Regular
+    _run "-_tcinsed_ml"  # regular
+    _run "-_tcinsed_ml_z" # regular with reset
+elif [[ "x$@" = "x-F" ]]; then
+    # regular with notfastpath
+    _run "-_tcinsed_ml_f"  # regular
+    _run "-_tcinsed_ml_zf" # regular with reset
+elif [[ "x$@" = "x-C" ]]; then
+    # codecgen
+    _run "-gx_tcinsed_ml" # codecgen: requires external
+    _run "-gxu_tcinsed_ml" # codecgen + unsafe
+    _run "-gxuw_tcinsed_ml" # codecgen + unsafe + maxinitlen
+elif [[ "x$@" = "x-X" ]]; then
+    # external
+    _run "-x_tcinsed_ml" # external
+elif [[ "x$@" = "x-h" || "x$@" = "x-?" ]]; then
+    cat <<EOF
+Usage: tests.sh [options...]
+  -A run through all tests (regular, external, codecgen)
+  -Z regular tests only 
+  -F regular tests only (without fastpath, so they run quickly)
+  -C codecgen only 
+  -X external only 
+  -h show help (usage)
+  -? same as -h
+  (no options) 
+      same as -A
+  (unrecognized options)
+      just pass on the options from the command line 
+EOF
+else
+    # e.g. ./tests.sh "-w_tcinsed_ml"
+    _run "$@"
+fi
diff --git a/vendor/github.com/ugorji/go/codec/time.go b/vendor/github.com/ugorji/go/codec/time.go
new file mode 100644
index 000000000..718b731ec
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/time.go
@@ -0,0 +1,233 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"fmt"
+	"reflect"
+	"time"
+)
+
+var (
+	timeDigits   = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
+	timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) {
+		defer panicToErr(&err)
+		bs = timeExt{}.WriteExt(rv.Interface())
+		return
+	}
+	timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) {
+		defer panicToErr(&err)
+		timeExt{}.ReadExt(rv.Interface(), bs)
+		return
+	}
+)
+
+type timeExt struct{}
+
+func (x timeExt) WriteExt(v interface{}) (bs []byte) {
+	switch v2 := v.(type) {
+	case time.Time:
+		bs = encodeTime(v2)
+	case *time.Time:
+		bs = encodeTime(*v2)
+	default:
+		panic(fmt.Errorf("unsupported format for time conversion: expecting time.Time; got %T", v2))
+	}
+	return
+}
+func (x timeExt) ReadExt(v interface{}, bs []byte) {
+	tt, err := decodeTime(bs)
+	if err != nil {
+		panic(err)
+	}
+	*(v.(*time.Time)) = tt
+}
+
+func (x timeExt) ConvertExt(v interface{}) interface{} {
+	return x.WriteExt(v)
+}
+func (x timeExt) UpdateExt(v interface{}, src interface{}) {
+	x.ReadExt(v, src.([]byte))
+}
+
+// EncodeTime encodes a time.Time as a []byte, including
+// information on the instant in time and UTC offset.
+//
+// Format Description
+//
+//   A timestamp is composed of 3 components:
+//
+//   - secs: signed integer representing seconds since unix epoch
+//   - nsces: unsigned integer representing fractional seconds as a
+//     nanosecond offset within secs, in the range 0 <= nsecs < 1e9
+//   - tz: signed integer representing timezone offset in minutes east of UTC,
+//     and a dst (daylight savings time) flag
+//
+//   When encoding a timestamp, the first byte is the descriptor, which
+//   defines which components are encoded and how many bytes are used to
+//   encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
+//   is not encoded in the byte array explicitly*.
+//
+//       Descriptor 8 bits are of the form `A B C DDD EE`:
+//           A:   Is secs component encoded? 1 = true
+//           B:   Is nsecs component encoded? 1 = true
+//           C:   Is tz component encoded? 1 = true
+//           DDD: Number of extra bytes for secs (range 0-7).
+//                If A = 1, secs encoded in DDD+1 bytes.
+//                    If A = 0, secs is not encoded, and is assumed to be 0.
+//                    If A = 1, then we need at least 1 byte to encode secs.
+//                    DDD says the number of extra bytes beyond that 1.
+//                    E.g. if DDD=0, then secs is represented in 1 byte.
+//                         if DDD=2, then secs is represented in 3 bytes.
+//           EE:  Number of extra bytes for nsecs (range 0-3).
+//                If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
+//
+//   Following the descriptor bytes, subsequent bytes are:
+//
+//       secs component encoded in `DDD + 1` bytes (if A == 1)
+//       nsecs component encoded in `EE + 1` bytes (if B == 1)
+//       tz component encoded in 2 bytes (if C == 1)
+//
+//   secs and nsecs components are integers encoded in a BigEndian
+//   2-complement encoding format.
+//
+//   tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
+//   Least significant bit 0 are described below:
+//
+//       Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
+//       Bit 15 = have\_dst: set to 1 if we set the dst flag.
+//       Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
+//       Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
+//
+func encodeTime(t time.Time) []byte {
+	//t := rv.Interface().(time.Time)
+	tsecs, tnsecs := t.Unix(), t.Nanosecond()
+	var (
+		bd   byte
+		btmp [8]byte
+		bs   [16]byte
+		i    int = 1
+	)
+	l := t.Location()
+	if l == time.UTC {
+		l = nil
+	}
+	if tsecs != 0 {
+		bd = bd | 0x80
+		bigen.PutUint64(btmp[:], uint64(tsecs))
+		f := pruneSignExt(btmp[:], tsecs >= 0)
+		bd = bd | (byte(7-f) << 2)
+		copy(bs[i:], btmp[f:])
+		i = i + (8 - f)
+	}
+	if tnsecs != 0 {
+		bd = bd | 0x40
+		bigen.PutUint32(btmp[:4], uint32(tnsecs))
+		f := pruneSignExt(btmp[:4], true)
+		bd = bd | byte(3-f)
+		copy(bs[i:], btmp[f:4])
+		i = i + (4 - f)
+	}
+	if l != nil {
+		bd = bd | 0x20
+		// Note that Go Libs do not give access to dst flag.
+		_, zoneOffset := t.Zone()
+		//zoneName, zoneOffset := t.Zone()
+		zoneOffset /= 60
+		z := uint16(zoneOffset)
+		bigen.PutUint16(btmp[:2], z)
+		// clear dst flags
+		bs[i] = btmp[0] & 0x3f
+		bs[i+1] = btmp[1]
+		i = i + 2
+	}
+	bs[0] = bd
+	return bs[0:i]
+}
+
+// DecodeTime decodes a []byte into a time.Time.
+func decodeTime(bs []byte) (tt time.Time, err error) {
+	bd := bs[0]
+	var (
+		tsec  int64
+		tnsec uint32
+		tz    uint16
+		i     byte = 1
+		i2    byte
+		n     byte
+	)
+	if bd&(1<<7) != 0 {
+		var btmp [8]byte
+		n = ((bd >> 2) & 0x7) + 1
+		i2 = i + n
+		copy(btmp[8-n:], bs[i:i2])
+		//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
+		if bs[i]&(1<<7) != 0 {
+			copy(btmp[0:8-n], bsAll0xff)
+			//for j,k := byte(0), 8-n; j < k; j++ {	btmp[j] = 0xff }
+		}
+		i = i2
+		tsec = int64(bigen.Uint64(btmp[:]))
+	}
+	if bd&(1<<6) != 0 {
+		var btmp [4]byte
+		n = (bd & 0x3) + 1
+		i2 = i + n
+		copy(btmp[4-n:], bs[i:i2])
+		i = i2
+		tnsec = bigen.Uint32(btmp[:])
+	}
+	if bd&(1<<5) == 0 {
+		tt = time.Unix(tsec, int64(tnsec)).UTC()
+		return
+	}
+	// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
+	// However, we need name here, so it can be shown when time is printed.
+	// Zone name is in form: UTC-08:00.
+	// Note that Go Libs do not give access to dst flag, so we ignore dst bits
+
+	i2 = i + 2
+	tz = bigen.Uint16(bs[i:i2])
+	i = i2
+	// sign extend sign bit into top 2 MSB (which were dst bits):
+	if tz&(1<<13) == 0 { // positive
+		tz = tz & 0x3fff //clear 2 MSBs: dst bits
+	} else { // negative
+		tz = tz | 0xc000 //set 2 MSBs: dst bits
+		//tzname[3] = '-' (TODO: verify. this works here)
+	}
+	tzint := int16(tz)
+	if tzint == 0 {
+		tt = time.Unix(tsec, int64(tnsec)).UTC()
+	} else {
+		// For Go Time, do not use a descriptive timezone.
+		// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
+		// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
+		// var zoneName = timeLocUTCName(tzint)
+		tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
+	}
+	return
+}
+
+func timeLocUTCName(tzint int16) string {
+	if tzint == 0 {
+		return "UTC"
+	}
+	var tzname = []byte("UTC+00:00")
+	//tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
+	//tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
+	var tzhr, tzmin int16
+	if tzint < 0 {
+		tzname[3] = '-' // (TODO: verify. this works here)
+		tzhr, tzmin = -tzint/60, (-tzint)%60
+	} else {
+		tzhr, tzmin = tzint/60, tzint%60
+	}
+	tzname[4] = timeDigits[tzhr/10]
+	tzname[5] = timeDigits[tzhr%10]
+	tzname[7] = timeDigits[tzmin/10]
+	tzname[8] = timeDigits[tzmin%10]
+	return string(tzname)
+	//return time.FixedZone(string(tzname), int(tzint)*60)
+}
diff --git a/vendor/github.com/ugorji/go/codec/xml.go b/vendor/github.com/ugorji/go/codec/xml.go
deleted file mode 100644
index 19fc36caf..000000000
--- a/vendor/github.com/ugorji/go/codec/xml.go
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build ignore
-
-package codec
-
-import "reflect"
-
-/*
-
-A strict Non-validating namespace-aware XML 1.0 parser and (en|de)coder.
-
-We are attempting this due to perceived issues with encoding/xml:
-  - Complicated. It tried to do too much, and is not as simple to use as json.
-  - Due to over-engineering, reflection is over-used AND performance suffers:
-    java is 6X faster:http://fabsk.eu/blog/category/informatique/dev/golang/
-    even PYTHON performs better: http://outgoing.typepad.com/outgoing/2014/07/exploring-golang.html
-
-codec framework will offer the following benefits
-  - VASTLY improved performance (when using reflection-mode or codecgen)
-  - simplicity and consistency: with the rest of the supported formats
-  - all other benefits of codec framework (streaming, codegeneration, etc)
-
-codec is not a drop-in replacement for encoding/xml.
-It is a replacement, based on the simplicity and performance of codec.
-Look at it like JAXB for Go.
-
-Challenges:
-  - Need to output XML preamble, with all namespaces at the right location in the output.
-  - Each "end" block is dynamic, so we need to maintain a context-aware stack
-  - How to decide when to use an attribute VS an element
-  - How to handle chardata, attr, comment EXPLICITLY.
-  - Should it output fragments?
-    e.g. encoding a bool should just output true OR false, which is not well-formed XML.
-
-Extend the struct tag. See representative example:
-  type X struct {
-    ID uint8 `codec:"http://ugorji.net/x-namespace xid id,omitempty,toarray,attr,cdata"`
-    // format: [namespace-uri ][namespace-prefix ]local-name, ...
-  }
-
-Based on this, we encode
-  - fields as elements, BUT
-    encode as attributes if struct tag contains ",attr" and is a scalar (bool, number or string)
-  - text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata".
-
-To handle namespaces:
-  - XMLHandle is denoted as being namespace-aware.
-    Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name.
-  - *Encoder and *Decoder know whether the Handle "prefers" namespaces.
-  - add *Encoder.getEncName(*structFieldInfo).
-    No one calls *structFieldInfo.indexForEncName directly anymore
-  - OR better yet: indexForEncName is namespace-aware, and helper.go is all namespace-aware
-    indexForEncName takes a parameter of the form namespace:local-name OR local-name
-  - add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc
-    by being a method on *Decoder, or maybe a method on the Handle itself.
-    No one accesses .encName anymore
-  - let encode.go and decode.go use these (for consistency)
-  - only problem exists for gen.go, where we create a big switch on encName.
-    Now, we also have to add a switch on strings.endsWith(kName, encNsName)
-    - gen.go will need to have many more methods, and then double-on the 2 switch loops like:
-      switch k {
-        case "abc" : x.abc()
-        case "def" : x.def()
-        default {
-          switch {
-            case !nsAware: panic(...)
-            case strings.endsWith(":abc"): x.abc()
-            case strings.endsWith(":def"): x.def()
-            default: panic(...)
-          }
-        }
-     }
-
-The structure below accommodates this:
-
-  type typeInfo struct {
-    sfi []*structFieldInfo // sorted by encName
-    sfins // sorted by namespace
-    sfia  // sorted, to have those with attributes at the top. Needed to write XML appropriately.
-    sfip  // unsorted
-  }
-  type structFieldInfo struct {
-    encName
-    nsEncName
-    ns string
-    attr bool
-    cdata bool
-  }
-
-indexForEncName is now an internal helper function that takes a sorted array
-(one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...)
-
-There will be a separate parser from the builder.
-The parser will have a method: next() xmlToken method. It has lookahead support,
-so you can pop multiple tokens, make a determination, and push them back in the order popped.
-This will be needed to determine whether we are "nakedly" decoding a container or not.
-The stack will be implemented using a slice and push/pop happens at the [0] element.
-
-xmlToken has fields:
-  - type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text
-  - value string
-  - ns string
-
-SEE: http://www.xml.com/pub/a/98/10/guide0.html?page=3#ENTDECL
-
-The following are skipped when parsing:
-  - External Entities (from external file)
-  - Notation Declaration e.g. <!NOTATION GIF87A SYSTEM "GIF">
-  - Entity Declarations & References
-  - XML Declaration (assume UTF-8)
-  - XML Directive i.e. <! ... >
-  - Other Declarations: Notation, etc.
-  - Comment
-  - Processing Instruction
-  - schema / DTD for validation:
-    We are not a VALIDATING parser. Validation is done elsewhere.
-    However, some parts of the DTD internal subset are used (SEE BELOW).
-    For Attribute List Declarations e.g.
-    <!ATTLIST foo:oldjoke name ID #REQUIRED label CDATA #IMPLIED status ( funny | notfunny ) 'funny' >
-    We considered using the ATTLIST to get "default" value, but not to validate the contents. (VETOED)
-
-The following XML features are supported
-  - Namespace
-  - Element
-  - Attribute
-  - cdata
-  - Unicode escape
-
-The following DTD (when as an internal sub-set) features are supported:
-  - Internal Entities e.g.
-    <!ELEMENT burns "ugorji is cool" > AND entities for the set: [<>&"']
-  - Parameter entities e.g.
-    <!ENTITY % personcontent "ugorji is cool"> <!ELEMENT burns (%personcontent;)*>
-
-At decode time, a structure containing the following is kept
-  - namespace mapping
-  - default attribute values
-  - all internal entities (<>&"' and others written in the document)
-
-When decode starts, it parses XML namespace declarations and creates a map in the
-xmlDecDriver. While parsing, that map continuously gets updated.
-The only problem happens when a namespace declaration happens on the node that it defines.
-e.g. <hn:name xmlns:hn="http://www.ugorji.net" >
-To handle this, each Element must be fully parsed at a time,
-even if it amounts to multiple tokens which are returned one at a time on request.
-
-xmlns is a special attribute name.
-  - It is used to define namespaces, including the default
-  - It is never returned as an AttrKey or AttrVal.
-  *We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.*
-
-Number, bool, null, mapKey, etc can all be decoded from any xmlToken.
-This accommodates map[int]string for example.
-
-It should be possible to create a schema from the types,
-or vice versa (generate types from schema with appropriate tags).
-This is however out-of-scope from this parsing project.
-
-We should write all namespace information at the first point that it is referenced in the tree,
-and use the mapping for all child nodes and attributes. This means that state is maintained
-at a point in the tree. This also means that calls to Decode or MustDecode will reset some state.
-
-When decoding, it is important to keep track of entity references and default attribute values.
-It seems these can only be stored in the DTD components. We should honor them when decoding.
-
-Configuration for XMLHandle will look like this:
-
-  XMLHandle
-    DefaultNS string
-    // Encoding:
-    NS map[string]string // ns URI to key, used for encoding
-    // Decoding: in case ENTITY declared in external schema or dtd, store info needed here
-    Entities map[string]string // map of entity rep to character
-
-
-During encode, if a namespace mapping is not defined for a namespace found on a struct,
-then we create a mapping for it using nsN (where N is 1..1000000, and doesn't conflict
-with any other namespace mapping).
-
-Note that different fields in a struct can have different namespaces.
-However, all fields will default to the namespace on the _struct field (if defined).
-
-An XML document is a name, a map of attributes and a list of children.
-Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example).
-We have to "DecodeNaked" into something that resembles XML data.
-
-To support DecodeNaked (decode into nil interface{}), we have to define some "supporting" types:
-    type Name struct { // Preferred. Less allocations due to conversions.
-      Local string
-      Space string
-    }
-    type Element struct {
-      Name Name
-      Attrs map[Name]string
-      Children []interface{} // each child is either *Element or string
-    }
-Only two "supporting" types are exposed for XML: Name and Element.
-
-// ------------------
-
-We considered 'type Name string' where Name is like "Space Local" (space-separated).
-We decided against it, because each creation of a name would lead to
-double allocation (first convert []byte to string, then concatenate them into a string).
-The benefit is that it is faster to read Attrs from a map. But given that Element is a value
-object, we want to eschew methods and have public exposed variables.
-
-We also considered the following, where xml types were not value objects, and we used
-intelligent accessor methods to extract information and for performance.
-*** WE DECIDED AGAINST THIS. ***
-    type Attr struct {
-      Name Name
-      Value string
-    }
-    // Element is a ValueObject: There are no accessor methods.
-    // Make element self-contained.
-    type Element struct {
-      Name Name
-      attrsMap map[string]string // where key is "Space Local"
-      attrs []Attr
-      childrenT []string
-      childrenE []Element
-      childrenI []int // each child is a index into T or E.
-    }
-    func (x *Element) child(i) interface{} // returns string or *Element
-
-// ------------------
-
-Per XML spec and our default handling, white space is always treated as
-insignificant between elements, except in a text node. The xml:space='preserve'
-attribute is ignored.
-
-**Note: there is no xml: namespace. The xml: attributes were defined before namespaces.**
-**So treat them as just "directives" that should be interpreted to mean something**.
-
-On encoding, we support indenting aka prettifying markup in the same way we support it for json.
-
-A document or element can only be encoded/decoded from/to a struct. In this mode:
-  - struct name maps to element name (or tag-info from _struct field)
-  - fields are mapped to child elements or attributes
-
-A map is either encoded as attributes on current element, or as a set of child elements.
-Maps are encoded as attributes iff their keys and values are primitives (number, bool, string).
-
-A list is encoded as a set of child elements.
-
-Primitives (number, bool, string) are encoded as an element, attribute or text
-depending on the context.
-
-Extensions must encode themselves as a text string.
-
-Encoding is tough, specifically when encoding mappings, because we need to encode
-as either attribute or element. To do this, we need to default to encoding as attributes,
-and then let Encoder inform the Handle when to start encoding as nodes.
-i.e. Encoder does something like:
-
-    h.EncodeMapStart()
-    h.Encode(), h.Encode(), ...
-    h.EncodeMapNotAttrSignal() // this is not a bool, because it's a signal
-    h.Encode(), h.Encode(), ...
-    h.EncodeEnd()
-
-Only XMLHandle understands this, and will set itself to start encoding as elements.
-
-This support extends to maps. For example, if a struct field is a map, and it has
-the struct tag signifying it should be attr, then all its fields are encoded as attributes.
-e.g.
-
-    type X struct {
-       M map[string]int `codec:"m,attr"` // encode keys as attributes named
-    }
-
-Question:
-  - if encoding a map, what if map keys have spaces in them???
-    Then they cannot be attributes or child elements. Error.
-
-Options to consider adding later:
-  - For attribute values, normalize by trimming beginning and ending white space,
-    and converting every white space sequence to a single space.
-  - ATTLIST restrictions are enforced.
-    e.g. default value of xml:space, skipping xml:XYZ style attributes, etc.
-  - Consider supporting NON-STRICT mode (e.g. to handle HTML parsing).
-    Some elements e.g. br, hr, etc need not close and should be auto-closed
-    ... (see http://www.w3.org/TR/html4/loose.dtd)
-    An expansive set of entities are pre-defined.
-  - Have easy way to create a HTML parser:
-    add a HTML() method to XMLHandle, that will set Strict=false, specify AutoClose,
-    and add HTML Entities to the list.
-  - Support validating element/attribute XMLName before writing it.
-    Keep this behind a flag, which is set to false by default (for performance).
-    type XMLHandle struct {
-      CheckName bool
-    }
-
-Misc:
-
-ROADMAP (1 weeks):
-  - build encoder (1 day)
-  - build decoder (based off xmlParser) (1 day)
-  - implement xmlParser (2 days).
-    Look at encoding/xml for inspiration.
-  - integrate and TEST (1 days)
-  - write article and post it (1 day)
-
-// ---------- MORE NOTES FROM 2017-11-30 ------------
-
-when parsing
-- parse the attributes first
-- then parse the nodes
-
-basically:
-- if encoding a field: we use the field name for the wrapper
-- if encoding a non-field, then just use the element type name
-
-  map[string]string ==> <map><key>abc</key><value>val</value></map>... or
-                        <map key="abc">val</map>... OR
-                        <key1>val1</key1><key2>val2</key2>...                <- PREFERED
-  []string  ==> <string>v1</string><string>v2</string>...
-  string v1 ==> <string>v1</string>
-  bool true ==> <bool>true</bool>
-  float 1.0 ==> <float>1.0</float>
-  ...
-
-  F1 map[string]string ==> <F1><key>abc</key><value>val</value></F1>... OR
-                           <F1 key="abc">val</F1>... OR
-                           <F1><abc>val</abc>...</F1>                        <- PREFERED
-  F2 []string          ==> <F2>v1</F2><F2>v2</F2>...
-  F3 bool              ==> <F3>true</F3>
-  ...
-
-- a scalar is encoded as:
-  (value) of type T  ==> <T><value/></T>
-  (value) of field F ==> <F><value/></F>
-- A kv-pair is encoded as:
-  (key,value) ==> <map><key><value/></key></map> OR <map key="value">
-  (key,value) of field F ==> <F><key><value/></key></F> OR <F key="value">
-- A map or struct is just a list of kv-pairs
-- A list is encoded as sequences of same node e.g.
-  <F1 key1="value11">
-  <F1 key2="value12">
-  <F2>value21</F2>
-  <F2>value22</F2>
-- we may have to singularize the field name, when entering into xml,
-  and pluralize them when encoding.
-- bi-directional encode->decode->encode is not a MUST.
-  even encoding/xml cannot decode correctly what was encoded:
-
-  see https://play.golang.org/p/224V_nyhMS
-  func main() {
-	fmt.Println("Hello, playground")
-	v := []interface{}{"hello", 1, true, nil, time.Now()}
-	s, err := xml.Marshal(v)
-	fmt.Printf("err: %v, \ns: %s\n", err, s)
-	var v2 []interface{}
-	err = xml.Unmarshal(s, &v2)
-	fmt.Printf("err: %v, \nv2: %v\n", err, v2)
-	type T struct {
-	    V []interface{}
-	}
-	v3 := T{V: v}
-	s, err = xml.Marshal(v3)
-	fmt.Printf("err: %v, \ns: %s\n", err, s)
-	var v4 T
-	err = xml.Unmarshal(s, &v4)
-	fmt.Printf("err: %v, \nv4: %v\n", err, v4)
-  }
-  Output:
-    err: <nil>,
-    s: <string>hello</string><int>1</int><bool>true</bool><Time>2009-11-10T23:00:00Z</Time>
-    err: <nil>,
-    v2: [<nil>]
-    err: <nil>,
-    s: <T><V>hello</V><V>1</V><V>true</V><V>2009-11-10T23:00:00Z</V></T>
-    err: <nil>,
-    v4: {[<nil> <nil> <nil> <nil>]}
--
-*/
-
-// ----------- PARSER  -------------------
-
-type xmlTokenType uint8
-
-const (
-	_ xmlTokenType = iota << 1
-	xmlTokenElemStart
-	xmlTokenElemEnd
-	xmlTokenAttrKey
-	xmlTokenAttrVal
-	xmlTokenText
-)
-
-type xmlToken struct {
-	Type      xmlTokenType
-	Value     string
-	Namespace string // blank for AttrVal and Text
-}
-
-type xmlParser struct {
-	r    decReader
-	toks []xmlToken // list of tokens.
-	ptr  int        // ptr into the toks slice
-	done bool       // nothing else to parse. r now returns EOF.
-}
-
-func (x *xmlParser) next() (t *xmlToken) {
-	// once x.done, or x.ptr == len(x.toks) == 0, then return nil (to signify finish)
-	if !x.done && len(x.toks) == 0 {
-		x.nextTag()
-	}
-	// parses one element at a time (into possible many tokens)
-	if x.ptr < len(x.toks) {
-		t = &(x.toks[x.ptr])
-		x.ptr++
-		if x.ptr == len(x.toks) {
-			x.ptr = 0
-			x.toks = x.toks[:0]
-		}
-	}
-	return
-}
-
-// nextTag will parses the next element and fill up toks.
-// It set done flag if/once EOF is reached.
-func (x *xmlParser) nextTag() {
-	// TODO: implement.
-}
-
-// ----------- ENCODER -------------------
-
-type xmlEncDriver struct {
-	e  *Encoder
-	w  encWriter
-	h  *XMLHandle
-	b  [64]byte // scratch
-	bs []byte   // scratch
-	// s  jsonStack
-	noBuiltInTypes
-}
-
-// ----------- DECODER -------------------
-
-type xmlDecDriver struct {
-	d    *Decoder
-	h    *XMLHandle
-	r    decReader // *bytesDecReader decReader
-	ct   valueType // container type. one of unset, array or map.
-	bstr [8]byte   // scratch used for string \UXXX parsing
-	b    [64]byte  // scratch
-
-	// wsSkipped bool // whitespace skipped
-
-	// s jsonStack
-
-	noBuiltInTypes
-}
-
-// DecodeNaked will decode into an XMLNode
-
-// XMLName is a value object representing a namespace-aware NAME
-type XMLName struct {
-	Local string
-	Space string
-}
-
-// XMLNode represents a "union" of the different types of XML Nodes.
-// Only one of fields (Text or *Element) is set.
-type XMLNode struct {
-	Element *Element
-	Text    string
-}
-
-// XMLElement is a value object representing an fully-parsed XML element.
-type XMLElement struct {
-	Name  Name
-	Attrs map[XMLName]string
-	// Children is a list of child nodes, each being a *XMLElement or string
-	Children []XMLNode
-}
-
-// ----------- HANDLE  -------------------
-
-type XMLHandle struct {
-	BasicHandle
-	textEncodingType
-
-	DefaultNS string
-	NS        map[string]string // ns URI to key, for encoding
-	Entities  map[string]string // entity representation to string, for encoding.
-}
-
-func (h *XMLHandle) newEncDriver(e *Encoder) encDriver {
-	return &xmlEncDriver{e: e, w: e.w, h: h}
-}
-
-func (h *XMLHandle) newDecDriver(d *Decoder) decDriver {
-	// d := xmlDecDriver{r: r.(*bytesDecReader), h: h}
-	hd := xmlDecDriver{d: d, r: d.r, h: h}
-	hd.n.bytes = d.b[:]
-	return &hd
-}
-
-func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
-}
-
-var _ decDriver = (*xmlDecDriver)(nil)
-var _ encDriver = (*xmlEncDriver)(nil)
diff --git a/vendor/github.com/xrash/smetrics/.travis.yml b/vendor/github.com/xrash/smetrics/.travis.yml
new file mode 100644
index 000000000..ec3a9c0ce
--- /dev/null
+++ b/vendor/github.com/xrash/smetrics/.travis.yml
@@ -0,0 +1,8 @@
+language: go
+go:
+    - 1.x
+    - 1.6
+    - 1.7
+    - master
+script:
+    - cd tests && make
diff --git a/vendor/github.com/xrash/smetrics/InfCont85.PDF b/vendor/github.com/xrash/smetrics/InfCont85.PDF
new file mode 100644
index 000000000..87eb4dc57
Binary files /dev/null and b/vendor/github.com/xrash/smetrics/InfCont85.PDF differ
diff --git a/vendor/github.com/xrash/smetrics/README.md b/vendor/github.com/xrash/smetrics/README.md
new file mode 100644
index 000000000..6e579dc3c
--- /dev/null
+++ b/vendor/github.com/xrash/smetrics/README.md
@@ -0,0 +1,120 @@
+# String metrics
+
+This library contains implementations of the Levenshtein distance, Jaro-Winkler and Soundex algorithms written in Go (golang). Other algorithms related with string metrics (or string similarity, whatever) are welcome.
+
+* master: [![Build Status](https://travis-ci.org/xrash/smetrics.svg?branch=master)](http://travis-ci.org/xrash/smetrics)
+
+# Algorithms
+
+## WagnerFischer
+
+        func WagnerFischer(a, b string, icost, dcost, scost int) int
+
+The Wagner-Fischer algorithm for calculating the Levenshtein distance. It runs on O(mn) and needs O(2m) space where m is the size of the smallest string. This is kinda optimized so it should be used in most cases.
+
+The first two parameters are the two strings to be compared. The last three parameters are the insertion cost, the deletion cost and the substitution cost. These are normally defined as 1, 1 and 2.
+
+#### Examples:
+
+        smetrics.WagnerFischer("POTATO", "POTATTO", 1, 1, 2)
+		>> 1, delete the second T on POTATTO
+
+        smetrics.WagnerFischer("MOUSE", "HOUSE", 2, 2, 4)
+		>> 4, substitute M for H
+
+## Ukkonen
+
+        func Ukkonen(a, b string, icost, dcost, scost int) int
+
+The Ukkonen algorithm for calculating the Levenshtein distance. The algorithm is described [here](http://www.cs.helsinki.fi/u/ukkonen/InfCont85.PDF). It runs on O(t . min(m, n)) where t is the actual distance between strings a and b, so this version should be preferred over the WagnerFischer for strings **very** similar. In practice, it's slower most of the times. It needs O(min(t, m, n)) space.
+
+The first two parameters are the two strings to be compared. The last three parameters are the insertion cost, the deletion cost and the substitution cost. These are normally defined as 1, 1 and 2.
+
+#### Examples:
+
+        smetrics.Ukkonen("POTATO", "POTATTO", 1, 1, 2)
+		>> 1, delete the second T on POTATTO
+
+        smetrics.Ukkonen("MOUSE", "HOUSE", 2, 2, 4)
+		>> 4, substitute M for H
+
+## Jaro
+
+        func Jaro(a, b string) float64
+
+The Jaro distance. It is not very accurate, therefore you should prefer the JaroWinkler optimized version.
+
+#### Examples:
+
+        smetrics.Jaro("AL", "AL")
+		>> 1, equal strings
+
+        smetrics.Jaro("MARTHA", "MARHTA")
+		>> 0.9444444444444445, very likely a typo
+
+        smetrics.Jaro("JONES", "JOHNSON")
+		>> 0.7904761904761904
+
+## JaroWinkler
+
+        func JaroWinkler(a, b string, boostThreshold float64, prefixSize int) float64
+
+The JaroWinkler distance. JaroWinkler returns a number between 0 and 1 where 1 means perfectly equal and 0 means completely different. It is commonly used on Record Linkage stuff, thus it tries to be accurate for real names and common typos. You should consider it on data such as person names and street names.
+
+JaroWinkler is a more accurate version of the Jaro algorithm. It works by boosting the score of exact matches at the beginning of the strings. By doing this, Winkler says that typos are less common to happen at the beginning. For this to happen, it introduces two more parameters: the boostThreshold and the prefixSize. These are commonly set to 0.7 and 4, respectively.
+
+#### Examples:
+
+        smetrics.JaroWinkler("AL", "AL", 0.7, 4)
+		>> 1, equal strings
+
+        smetrics.JaroWinkler("MARTHA", "MARHTA", 0.7, 4)
+		>> 0.9611111111111111, very likely a typo
+
+        smetrics.JaroWinkler("JONES", "JOHNSON", 0.7, 4)
+		>> 0.8323809523809523
+
+## Soundex
+
+        func Soundex(s string) string
+
+The Soundex encoding. It is a phonetic algorithm that considers how the words sound in english. Soundex maps a name to a 4-byte string consisting of the first letter of the original string and three numbers. Strings that sound similar should map to the same thing.
+
+#### Examples:
+
+        smetrics.Soundex("Euler")
+		>> E460
+
+        smetrics.Soundex("Ellery")
+		>> E460
+
+        smetrics.Soundex("Lloyd")
+		>> L300
+
+        smetrics.Soundex("Ladd")
+		>> L300
+
+## Hamming
+
+        func Hamming(a, b string) (int, error)
+
+The Hamming distance is simply the minimum number of substitutions required to change one string into the other. Both strings must have the same size, of the function returns an error.
+
+#### Examples:
+
+        smetrics.Hamming("aaa", "aaa")
+		>> 0, nil
+
+        smetrics.Hamming("aaa", "aab")
+		>> 1, nil
+
+        smetrics.Hamming("aaaa", "a")
+		>> -1, error
+
+# TODO
+
+- Accept cost functions instead of constant values in every Levenshtein implementation.
+
+- Make a better interface.
+
+- Moar algos!
diff --git a/vendor/go.bug.st/serial.v1/.travis.yml b/vendor/go.bug.st/serial.v1/.travis.yml
new file mode 100644
index 000000000..6cbc8139c
--- /dev/null
+++ b/vendor/go.bug.st/serial.v1/.travis.yml
@@ -0,0 +1,70 @@
+language: go
+
+os:
+  - linux
+  - osx
+
+go:
+  - 1.7.x
+  - 1.8.x
+  - 1.9.x
+  - 1.10.x
+  - 1.11.x
+
+go_import_path: go.bug.st/serial.v1
+
+env:
+  - TEST_OS=linux TEST_ARCH=386
+  - TEST_OS=linux TEST_ARCH=amd64
+  - TEST_OS=linux TEST_ARCH=arm
+  - TEST_OS=windows TEST_ARCH=386
+  - TEST_OS=windows TEST_ARCH=amd64
+  - TEST_OS=darwin TEST_ARCH=386
+  - TEST_OS=darwin TEST_ARCH=amd64
+  - TEST_OS=freebsd TEST_ARCH=amd64
+  - TEST_OS=openbsd TEST_ARCH=amd64
+  - TEST_OS=openbsd TEST_ARCH=386
+  - TEST_OS=openbsd TEST_ARCH=arm
+
+matrix:
+  exclude:
+  - os: linux
+    env: TEST_OS=darwin TEST_ARCH=386
+  - os: linux
+    env: TEST_OS=darwin TEST_ARCH=amd64
+  - os: osx
+    env: TEST_OS=linux TEST_ARCH=386
+  - os: osx
+    env: TEST_OS=linux TEST_ARCH=amd64
+  - os: osx
+    env: TEST_OS=linux TEST_ARCH=arm
+  - os: osx
+    env: TEST_OS=windows TEST_ARCH=386
+  - os: osx
+    env: TEST_OS=windows TEST_ARCH=amd64
+  - os: osx
+    env: TEST_OS=freebsd TEST_ARCH=amd64
+  - os: osx
+    env: TEST_OS=openbsd TEST_ARCH=amd64
+  - os: osx
+    env: TEST_OS=openbsd TEST_ARCH=386
+  - os: osx
+    env: TEST_OS=openbsd TEST_ARCH=arm
+  allow_failures:
+    - env: TEST_OS=openbsd TEST_ARCH=arm
+
+before_install:
+
+script:
+  - GOARM=5 GO386=387 GOOS=$TEST_OS GOARCH=$TEST_ARCH go get github.com/stretchr/testify/require
+  - GOARM=5 GO386=387 GOOS=$TEST_OS GOARCH=$TEST_ARCH go get golang.org/x/sys/windows
+  - GOARM=5 GO386=387 GOOS=$TEST_OS GOARCH=$TEST_ARCH go build -v go.bug.st/serial.v1
+  - GOARM=5 GO386=387 GOOS=$TEST_OS GOARCH=$TEST_ARCH go test -c -v go.bug.st/serial.v1
+
+notifications:
+  email:
+    recipients:
+      - c.maglie@bug.st
+    on_success: change
+    on_failure: always
+
diff --git a/vendor/go.bug.st/serial.v1/README.md b/vendor/go.bug.st/serial.v1/README.md
new file mode 100644
index 000000000..4ff3ccb4e
--- /dev/null
+++ b/vendor/go.bug.st/serial.v1/README.md
@@ -0,0 +1,35 @@
+[![Build Status](https://travis-ci.org/bugst/go-serial.svg?branch=v1)](https://travis-ci.org/bugst/go-serial)
+
+# go.bug.st/serial.v1
+
+A cross-platform serial library for go-lang.
+
+## Documentation and examples
+
+See the godoc here: https://godoc.org/go.bug.st/serial.v1
+
+## Development
+
+If you want to contribute to the development of this library, you must clone this git repository directly into your `src` folder under `src/go.bug.st/serial.v1` and checkout the branch `v1`.
+
+```
+cd $GOPATH
+mkdir -p src/go.bug.st/
+git clone https://github.com/bugst/go-serial.git -b v1 src/go.bug.st/serial.v1
+go test go.bug.st/serial.v1
+```
+
+## What's new in v1
+
+There are some API improvements, in particular object naming is now more idiomatic, class names are less redundant (for example `serial.SerialPort` is now called `serial.Port`), some internal class fields, constants or enumerations are now private and some methods have been moved into the proper interface.
+
+If you come from the version v0 and want to see the full list of API changes, please check this pull request:
+
+https://github.com/bugst/go-serial/pull/5/files
+
+## License
+
+The software is release under a BSD 3-clause license
+
+https://github.com/bugst/go-serial/blob/v1/LICENSE
+
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
index 122c03e70..e86e89661 100644
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -484,6 +484,7 @@ userAuthLoop:
 				// sig.Format.  This is usually the same, but
 				// for certs, the names differ.
 				if !isAcceptableAlgo(sig.Format) {
+					authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
 					break
 				}
 				signedData := buildDataSignedForAuth(sessionID, userAuthReq, algoBytes, pubKeyData)
diff --git a/vendor/golang.org/x/net/internal/socket/empty.s b/vendor/golang.org/x/net/internal/socket/empty.s
new file mode 100644
index 000000000..bff0231c7
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/empty.s
@@ -0,0 +1,7 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin,go1.12
+
+// This exists solely so we can linkname in symbols from syscall.
diff --git a/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go b/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go
new file mode 100644
index 000000000..02d2b3cc8
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go
@@ -0,0 +1,33 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.12
+
+package socket
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+	l := uint32(len(b))
+	_, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
+	return int(l), errnoErr(errno)
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+	_, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
+	return errnoErr(errno)
+}
+
+func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
+	n, _, errno := syscall.Syscall(syscall.SYS_RECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
+	return int(n), errnoErr(errno)
+}
+
+func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+	n, _, errno := syscall.Syscall(syscall.SYS_SENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
+	return int(n), errnoErr(errno)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_go1_12_darwin.go b/vendor/golang.org/x/net/internal/socket/sys_go1_12_darwin.go
new file mode 100644
index 000000000..0999a19fb
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/sys_go1_12_darwin.go
@@ -0,0 +1,42 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.12
+
+package socket
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+//go:linkname syscall_getsockopt syscall.getsockopt
+func syscall_getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *uint32) error
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+	l := uint32(len(b))
+	err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
+	return int(l), err
+}
+
+//go:linkname syscall_setsockopt syscall.setsockopt
+func syscall_setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+	return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
+}
+
+//go:linkname syscall_recvmsg syscall.recvmsg
+func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error)
+
+func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
+	return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
+}
+
+//go:linkname syscall_sendmsg syscall.sendmsg
+func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error)
+
+func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+	return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_posix.go b/vendor/golang.org/x/net/internal/socket/sys_posix.go
index dc130c27e..9a9bc4762 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_posix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_posix.go
@@ -121,18 +121,21 @@ var zoneCache = ipv6ZoneCache{
 	toName:  make(map[int]string),
 }
 
-func (zc *ipv6ZoneCache) update(ift []net.Interface) {
+// update refreshes the network interface information if the cache was last
+// updated more than 1 minute ago, or if force is set. It returns whether the
+// cache was updated.
+func (zc *ipv6ZoneCache) update(ift []net.Interface, force bool) (updated bool) {
 	zc.Lock()
 	defer zc.Unlock()
 	now := time.Now()
-	if zc.lastFetched.After(now.Add(-60 * time.Second)) {
-		return
+	if !force && zc.lastFetched.After(now.Add(-60*time.Second)) {
+		return false
 	}
 	zc.lastFetched = now
 	if len(ift) == 0 {
 		var err error
 		if ift, err = net.Interfaces(); err != nil {
-			return
+			return false
 		}
 	}
 	zc.toIndex = make(map[string]int, len(ift))
@@ -143,25 +146,38 @@ func (zc *ipv6ZoneCache) update(ift []net.Interface) {
 			zc.toName[ifi.Index] = ifi.Name
 		}
 	}
+	return true
 }
 
 func (zc *ipv6ZoneCache) name(zone int) string {
-	zoneCache.update(nil)
+	updated := zoneCache.update(nil, false)
 	zoneCache.RLock()
-	defer zoneCache.RUnlock()
 	name, ok := zoneCache.toName[zone]
-	if !ok {
+	zoneCache.RUnlock()
+	if !ok && !updated {
+		zoneCache.update(nil, true)
+		zoneCache.RLock()
+		name, ok = zoneCache.toName[zone]
+		zoneCache.RUnlock()
+	}
+	if !ok { // last resort
 		name = strconv.Itoa(zone)
 	}
 	return name
 }
 
 func (zc *ipv6ZoneCache) index(zone string) int {
-	zoneCache.update(nil)
+	updated := zoneCache.update(nil, false)
 	zoneCache.RLock()
-	defer zoneCache.RUnlock()
 	index, ok := zoneCache.toIndex[zone]
-	if !ok {
+	zoneCache.RUnlock()
+	if !ok && !updated {
+		zoneCache.update(nil, true)
+		zoneCache.RLock()
+		index, ok = zoneCache.toIndex[zone]
+		zoneCache.RUnlock()
+	}
+	if !ok { // last resort
 		index, _ = strconv.Atoi(zone)
 	}
 	return index
diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go
index 18eba3085..0eb71283f 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux,!s390x,!386 netbsd openbsd
+// +build dragonfly freebsd linux,!s390x,!386 netbsd openbsd
 
 package socket
 
diff --git a/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go
index 3efa29037..863d55b8d 100644
--- a/vendor/golang.org/x/net/ipv4/doc.go
+++ b/vendor/golang.org/x/net/ipv4/doc.go
@@ -241,4 +241,5 @@
 // IncludeSourceSpecificGroup may return an error.
 package ipv4 // import "golang.org/x/net/ipv4"
 
-// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
+// BUG(mikio): This package is not implemented on AIX, JS, NaCl and
+// Plan 9.
diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go
index 204a49fea..a7c892dc4 100644
--- a/vendor/golang.org/x/net/ipv4/payload_cmsg.go
+++ b/vendor/golang.org/x/net/ipv4/payload_cmsg.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !js,!nacl,!plan9,!windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv4
 
diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go b/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go
index 8d45599f4..15a27b7a0 100644
--- a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go
+++ b/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_8.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build !go1.9
-// +build !js,!nacl,!plan9,!windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv4
 
diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go b/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go
index 4081aad8b..aab3b224e 100644
--- a/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go
+++ b/vendor/golang.org/x/net/ipv4/payload_cmsg_go1_9.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build go1.9
-// +build !js,!nacl,!plan9,!windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv4
 
diff --git a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
index 1d434c61a..d57f05c10 100644
--- a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
+++ b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build js nacl plan9 windows
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
 
 package ipv4
 
diff --git a/vendor/golang.org/x/net/ipv6/doc.go b/vendor/golang.org/x/net/ipv6/doc.go
index e0be9d50d..d38ea0da6 100644
--- a/vendor/golang.org/x/net/ipv6/doc.go
+++ b/vendor/golang.org/x/net/ipv6/doc.go
@@ -240,4 +240,5 @@
 // IncludeSourceSpecificGroup may return an error.
 package ipv6 // import "golang.org/x/net/ipv6"
 
-// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
+// BUG(mikio): This package is not implemented on AIX, JS, NaCl and
+// Plan 9.
diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg.go b/vendor/golang.org/x/net/ipv6/payload_cmsg.go
index 3f23b5d21..e17847d0b 100644
--- a/vendor/golang.org/x/net/ipv6/payload_cmsg.go
+++ b/vendor/golang.org/x/net/ipv6/payload_cmsg.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !js,!nacl,!plan9,!windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv6
 
diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go b/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go
index bc4209db7..a48a6ed64 100644
--- a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go
+++ b/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_8.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build !go1.9
-// +build !js,!nacl,!plan9,!windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv6
 
diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go b/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go
index 7dd650480..fb196ed80 100644
--- a/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go
+++ b/vendor/golang.org/x/net/ipv6/payload_cmsg_go1_9.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build go1.9
-// +build !js,!nacl,!plan9,!windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv6
 
diff --git a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
index 459142d26..bfb544784 100644
--- a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
+++ b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build js nacl plan9 windows
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
 
 package ipv6
 
diff --git a/vendor/golang.org/x/sys/unix/.gitignore b/vendor/golang.org/x/sys/unix/.gitignore
new file mode 100644
index 000000000..e3e0fc6f8
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/.gitignore
@@ -0,0 +1,2 @@
+_obj/
+unix.test
diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md
new file mode 100644
index 000000000..bc6f6031f
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/README.md
@@ -0,0 +1,173 @@
+# Building `sys/unix`
+
+The sys/unix package provides access to the raw system call interface of the
+underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
+
+Porting Go to a new architecture/OS combination or adding syscalls, types, or
+constants to an existing architecture/OS pair requires some manual effort;
+however, there are tools that automate much of the process.
+
+## Build Systems
+
+There are currently two ways we generate the necessary files. We are currently
+migrating the build system to use containers so the builds are reproducible.
+This is being done on an OS-by-OS basis. Please update this documentation as
+components of the build system change.
+
+### Old Build System (currently for `GOOS != "Linux" || GOARCH == "sparc64"`)
+
+The old build system generates the Go files based on the C header files
+present on your system. This means that files
+for a given GOOS/GOARCH pair must be generated on a system with that OS and
+architecture. This also means that the generated code can differ from system
+to system, based on differences in the header files.
+
+To avoid this, if you are using the old build system, only generate the Go
+files on an installation with unmodified header files. It is also important to
+keep track of which version of the OS the files were generated from (ex.
+Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
+and have each OS upgrade correspond to a single change.
+
+To build the files for your current OS and architecture, make sure GOOS and
+GOARCH are set correctly and run `mkall.sh`. This will generate the files for
+your specific system. Running `mkall.sh -n` shows the commands that will be run.
+
+Requirements: bash, perl, go
+
+### New Build System (currently for `GOOS == "Linux" && GOARCH != "sparc64"`)
+
+The new build system uses a Docker container to generate the go files directly
+from source checkouts of the kernel and various system libraries. This means
+that on any platform that supports Docker, all the files using the new build
+system can be generated at once, and generated files will not change based on
+what the person running the scripts has installed on their computer.
+
+The OS specific files for the new build system are located in the `${GOOS}`
+directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
+the kernel or system library updates, modify the Dockerfile at
+`${GOOS}/Dockerfile` to checkout the new release of the source.
+
+To build all the files under the new build system, you must be on an amd64/Linux
+system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
+then generate all of the files for all of the GOOS/GOARCH pairs in the new build
+system. Running `mkall.sh -n` shows the commands that will be run.
+
+Requirements: bash, perl, go, docker
+
+## Component files
+
+This section describes the various files used in the code generation process.
+It also contains instructions on how to modify these files to add a new
+architecture/OS or to add additional syscalls, types, or constants. Note that
+if you are using the new build system, the scripts cannot be called normally.
+They must be called from within the docker container.
+
+### asm files
+
+The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
+call dispatch. There are three entry points:
+```
+  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+```
+The first and second are the standard ones; they differ only in how many
+arguments can be passed to the kernel. The third is for low-level use by the
+ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
+let it know that a system call is running.
+
+When porting Go to an new architecture/OS, this file must be implemented for
+each GOOS/GOARCH pair.
+
+### mksysnum
+
+Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl`
+for the old system). This script takes in a list of header files containing the
+syscall number declarations and parses them to produce the corresponding list of
+Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
+constants.
+
+Adding new syscall numbers is mostly done by running the build on a sufficiently
+new installation of the target OS (or updating the source checkouts for the
+new build system). However, depending on the OS, you make need to update the
+parsing in mksysnum.
+
+### mksyscall.pl
+
+The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
+hand-written Go files which implement system calls (for unix, the specific OS,
+or the specific OS/Architecture pair respectively) that need special handling
+and list `//sys` comments giving prototypes for ones that can be generated.
+
+The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts
+them into syscalls. This requires the name of the prototype in the comment to
+match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
+prototype can be exported (capitalized) or not.
+
+Adding a new syscall often just requires adding a new `//sys` function prototype
+with the desired arguments and a capitalized name so it is exported. However, if
+you want the interface to the syscall to be different, often one will make an
+unexported `//sys` prototype, an then write a custom wrapper in
+`syscall_${GOOS}.go`.
+
+### types files
+
+For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
+`types_${GOOS}.go` on the old system). This file includes standard C headers and
+creates Go type aliases to the corresponding C types. The file is then fed
+through godef to get the Go compatible definitions. Finally, the generated code
+is fed though mkpost.go to format the code correctly and remove any hidden or
+private identifiers. This cleaned-up code is written to
+`ztypes_${GOOS}_${GOARCH}.go`.
+
+The hardest part about preparing this file is figuring out which headers to
+include and which symbols need to be `#define`d to get the actual data
+structures that pass through to the kernel system calls. Some C libraries
+preset alternate versions for binary compatibility and translate them on the
+way in and out of system calls, but there is almost always a `#define` that can
+get the real ones.
+See `types_darwin.go` and `linux/types.go` for examples.
+
+To add a new type, add in the necessary include statement at the top of the
+file (if it is not already there) and add in a type alias line. Note that if
+your type is significantly different on different architectures, you may need
+some `#if/#elif` macros in your include statements.
+
+### mkerrors.sh
+
+This script is used to generate the system's various constants. This doesn't
+just include the error numbers and error strings, but also the signal numbers
+an a wide variety of miscellaneous constants. The constants come from the list
+of include files in the `includes_${uname}` variable. A regex then picks out
+the desired `#define` statements, and generates the corresponding Go constants.
+The error numbers and strings are generated from `#include <errno.h>`, and the
+signal numbers and strings are generated from `#include <signal.h>`. All of
+these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
+`_errors.c`, which prints out all the constants.
+
+To add a constant, add the header that includes it to the appropriate variable.
+Then, edit the regex (if necessary) to match the desired constant. Avoid making
+the regex too broad to avoid matching unintended constants.
+
+
+## Generated files
+
+### `zerror_${GOOS}_${GOARCH}.go`
+
+A file containing all of the system's generated error numbers, error strings,
+signal numbers, and constants. Generated by `mkerrors.sh` (see above).
+
+### `zsyscall_${GOOS}_${GOARCH}.go`
+
+A file containing all the generated syscalls for a specific GOOS and GOARCH.
+Generated by `mksyscall.pl` (see above).
+
+### `zsysnum_${GOOS}_${GOARCH}.go`
+
+A list of numeric constants for all the syscall number of the specific GOOS
+and GOARCH. Generated by mksysnum (see above).
+
+### `ztypes_${GOOS}_${GOARCH}.go`
+
+A file containing Go types for passing into (or returning from) syscalls.
+Generated by godefs and the types file (see above).
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
index 649e58714..88f712557 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
@@ -15,12 +15,6 @@
 // Just jump to package syscall's implementation for all these functions.
 // The runtime may know about them.
 
-TEXT ·Syscall(SB),NOSPLIT,$0-56
-	BR	syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
-	BR	syscall·Syscall6(SB)
-
 TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
 	BL	runtime·entersyscall(SB)
 	MOVD	a1+8(FP), R3
@@ -36,12 +30,6 @@ TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
 	BL	runtime·exitsyscall(SB)
 	RET
 
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	BR	syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
-	BR	syscall·RawSyscall6(SB)
-
 TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
 	MOVD	a1+8(FP), R3
 	MOVD	a2+16(FP), R4
diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh
new file mode 100755
index 000000000..9b76ad669
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mkall.sh
@@ -0,0 +1,204 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This script runs or (given -n) prints suggested commands to generate files for
+# the Architecture/OS specified by the GOARCH and GOOS environment variables.
+# See README.md for more information about how the build system works.
+
+GOOSARCH="${GOOS}_${GOARCH}"
+
+# defaults
+mksyscall="./mksyscall.pl"
+mkerrors="./mkerrors.sh"
+zerrors="zerrors_$GOOSARCH.go"
+mksysctl=""
+zsysctl="zsysctl_$GOOSARCH.go"
+mksysnum=
+mktypes=
+run="sh"
+cmd=""
+
+case "$1" in
+-syscalls)
+	for i in zsyscall*go
+	do
+		# Run the command line that appears in the first line
+		# of the generated file to regenerate it.
+		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
+		rm _$i
+	done
+	exit 0
+	;;
+-n)
+	run="cat"
+	cmd="echo"
+	shift
+esac
+
+case "$#" in
+0)
+	;;
+*)
+	echo 'usage: mkall.sh [-n]' 1>&2
+	exit 2
+esac
+
+if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
+	# Use then new build system
+	# Files generated through docker (use $cmd so you can Ctl-C the build or run)
+	$cmd docker build --tag generate:$GOOS $GOOS
+	$cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS
+	exit
+fi
+
+GOOSARCH_in=syscall_$GOOSARCH.go
+case "$GOOSARCH" in
+_* | *_ | _)
+	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
+	exit 1
+	;;
+aix_ppc)
+	mkerrors="$mkerrors -maix32"
+	mksyscall="./mksyscall_aix_ppc.pl -aix"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+aix_ppc64)
+	mkerrors="$mkerrors -maix64"
+	mksyscall="./mksyscall_aix_ppc64.pl -aix"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+darwin_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32"
+	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+darwin_amd64)
+	mkerrors="$mkerrors -m64"
+	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+darwin_arm)
+	mkerrors="$mkerrors"
+	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+darwin_arm64)
+	mkerrors="$mkerrors -m64"
+	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+dragonfly_amd64)
+	mkerrors="$mkerrors -m64"
+	mksyscall="./mksyscall.pl -dragonfly"
+	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+freebsd_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32"
+	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+freebsd_amd64)
+	mkerrors="$mkerrors -m64"
+	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+freebsd_arm)
+	mkerrors="$mkerrors"
+	mksyscall="./mksyscall.pl -l32 -arm"
+	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+	# Let the type of C char be signed for making the bare syscall
+	# API consistent across platforms.
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
+linux_sparc64)
+	GOOSARCH_in=syscall_linux_sparc64.go
+	unistd_h=/usr/include/sparc64-linux-gnu/asm/unistd.h
+	mkerrors="$mkerrors -m64"
+	mksysnum="./mksysnum_linux.pl $unistd_h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+netbsd_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32 -netbsd"
+	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+netbsd_amd64)
+	mkerrors="$mkerrors -m64"
+	mksyscall="./mksyscall.pl -netbsd"
+	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+netbsd_arm)
+	mkerrors="$mkerrors"
+	mksyscall="./mksyscall.pl -l32 -netbsd -arm"
+	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
+	# Let the type of C char be signed for making the bare syscall
+	# API consistent across platforms.
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
+openbsd_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32 -openbsd"
+	mksysctl="./mksysctl_openbsd.pl"
+	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+openbsd_amd64)
+	mkerrors="$mkerrors -m64"
+	mksyscall="./mksyscall.pl -openbsd"
+	mksysctl="./mksysctl_openbsd.pl"
+	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+openbsd_arm)
+	mkerrors="$mkerrors"
+	mksyscall="./mksyscall.pl -l32 -openbsd -arm"
+	mksysctl="./mksysctl_openbsd.pl"
+	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
+	# Let the type of C char be signed for making the bare syscall
+	# API consistent across platforms.
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
+solaris_amd64)
+	mksyscall="./mksyscall_solaris.pl"
+	mkerrors="$mkerrors -m64"
+	mksysnum=
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+*)
+	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
+	exit 1
+	;;
+esac
+
+(
+	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
+	case "$GOOS" in
+	*)
+		syscall_goos="syscall_$GOOS.go"
+		case "$GOOS" in
+		darwin | dragonfly | freebsd | netbsd | openbsd)
+			syscall_goos="syscall_bsd.go $syscall_goos"
+			;;
+		esac
+		if [ -n "$mksyscall" ]; then
+			if [ "$GOOSARCH" == "aix_ppc64" ]; then
+				# aix/ppc64 script generates files instead of writing to stdin.
+				echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
+			else
+				echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
+			fi
+		fi
+	esac
+	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
+	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
+	if [ -n "$mktypes" ]; then
+		echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go";
+	fi
+) | $run
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
new file mode 100755
index 000000000..955dd50f9
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -0,0 +1,658 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Generate Go code listing errors and other #defined constant
+# values (ENAMETOOLONG etc.), by asking the preprocessor
+# about the definitions.
+
+unset LANG
+export LC_ALL=C
+export LC_CTYPE=C
+
+if test -z "$GOARCH" -o -z "$GOOS"; then
+	echo 1>&2 "GOARCH or GOOS not defined in environment"
+	exit 1
+fi
+
+# Check that we are using the new build system if we should
+if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
+	if [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then
+		echo 1>&2 "In the new build system, mkerrors should not be called directly."
+		echo 1>&2 "See README.md"
+		exit 1
+	fi
+fi
+
+if [[ "$GOOS" = "aix" ]]; then
+	CC=${CC:-gcc}
+else
+	CC=${CC:-cc}
+fi
+
+if [[ "$GOOS" = "solaris" ]]; then
+	# Assumes GNU versions of utilities in PATH.
+	export PATH=/usr/gnu/bin:$PATH
+fi
+
+uname=$(uname)
+
+includes_AIX='
+#include <net/if.h>
+#include <net/netopt.h>
+#include <netinet/ip_mroute.h>
+#include <sys/protosw.h>
+#include <sys/stropts.h>
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <sys/termio.h>
+#include <termios.h>
+#include <fcntl.h>
+
+#define AF_LOCAL AF_UNIX
+'
+
+includes_Darwin='
+#define _DARWIN_C_SOURCE
+#define KERNEL
+#define _DARWIN_USE_64_BIT_INODE
+#include <stdint.h>
+#include <sys/attr.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/ptrace.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <sys/xattr.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <termios.h>
+'
+
+includes_DragonFly='
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <termios.h>
+#include <netinet/ip.h>
+#include <net/ip_mroute/ip_mroute.h>
+'
+
+includes_FreeBSD='
+#include <sys/capsicum.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <termios.h>
+#include <netinet/ip.h>
+#include <netinet/ip_mroute.h>
+#include <sys/extattr.h>
+
+#if __FreeBSD__ >= 10
+#define IFT_CARP	0xf8	// IFT_CARP is deprecated in FreeBSD 10
+#undef SIOCAIFADDR
+#define SIOCAIFADDR	_IOW(105, 26, struct oifaliasreq)	// ifaliasreq contains if_data
+#undef SIOCSIFPHYADDR
+#define SIOCSIFPHYADDR	_IOW(105, 70, struct oifaliasreq)	// ifaliasreq contains if_data
+#endif
+'
+
+includes_Linux='
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#ifndef __LP64__
+#define _FILE_OFFSET_BITS 64
+#endif
+#define _GNU_SOURCE
+
+// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of
+// these structures. We just include them copied from <bits/termios.h>.
+#if defined(__powerpc__)
+struct sgttyb {
+        char    sg_ispeed;
+        char    sg_ospeed;
+        char    sg_erase;
+        char    sg_kill;
+        short   sg_flags;
+};
+
+struct tchars {
+        char    t_intrc;
+        char    t_quitc;
+        char    t_startc;
+        char    t_stopc;
+        char    t_eofc;
+        char    t_brkc;
+};
+
+struct ltchars {
+        char    t_suspc;
+        char    t_dsuspc;
+        char    t_rprntc;
+        char    t_flushc;
+        char    t_werasc;
+        char    t_lnextc;
+};
+#endif
+
+#include <bits/sockaddr.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <sys/inotify.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/xattr.h>
+#include <linux/if.h>
+#include <linux/if_alg.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/if_ppp.h>
+#include <linux/if_tun.h>
+#include <linux/if_packet.h>
+#include <linux/if_addr.h>
+#include <linux/falloc.h>
+#include <linux/filter.h>
+#include <linux/fs.h>
+#include <linux/kexec.h>
+#include <linux/keyctl.h>
+#include <linux/magic.h>
+#include <linux/memfd.h>
+#include <linux/module.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <linux/net_namespace.h>
+#include <linux/perf_event.h>
+#include <linux/random.h>
+#include <linux/reboot.h>
+#include <linux/rtnetlink.h>
+#include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/seccomp.h>
+#include <linux/sockios.h>
+#include <linux/wait.h>
+#include <linux/icmpv6.h>
+#include <linux/serial.h>
+#include <linux/can.h>
+#include <linux/vm_sockets.h>
+#include <linux/taskstats.h>
+#include <linux/genetlink.h>
+#include <linux/watchdog.h>
+#include <linux/hdreg.h>
+#include <linux/rtc.h>
+#include <linux/if_xdp.h>
+#include <mtd/ubi-user.h>
+#include <net/route.h>
+#include <asm/termbits.h>
+
+#ifndef MSG_FASTOPEN
+#define MSG_FASTOPEN    0x20000000
+#endif
+
+#ifndef PTRACE_GETREGS
+#define PTRACE_GETREGS	0xc
+#endif
+
+#ifndef PTRACE_SETREGS
+#define PTRACE_SETREGS	0xd
+#endif
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK	270
+#endif
+
+#ifdef SOL_BLUETOOTH
+// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
+// but it is already in bluetooth_linux.go
+#undef SOL_BLUETOOTH
+#endif
+
+// Certain constants are missing from the fs/crypto UAPI
+#define FS_KEY_DESC_PREFIX              "fscrypt:"
+#define FS_KEY_DESC_PREFIX_SIZE         8
+#define FS_MAX_KEY_SIZE                 64
+
+// XDP socket constants do not appear to be picked up otherwise.
+// Copied from samples/bpf/xdpsock_user.c.
+#ifndef SOL_XDP
+#define SOL_XDP 283
+#endif
+
+#ifndef AF_XDP
+#define AF_XDP 44
+#endif
+'
+
+includes_NetBSD='
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/event.h>
+#include <sys/extattr.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/termios.h>
+#include <sys/ttycom.h>
+#include <sys/wait.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_mroute.h>
+#include <netinet/if_ether.h>
+
+// Needed since <sys/param.h> refers to it...
+#define schedppq 1
+'
+
+includes_OpenBSD='
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/termios.h>
+#include <sys/ttycom.h>
+#include <sys/unistd.h>
+#include <sys/wait.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_mroute.h>
+#include <netinet/if_ether.h>
+#include <net/if_bridge.h>
+
+// We keep some constants not supported in OpenBSD 5.5 and beyond for
+// the promise of compatibility.
+#define EMUL_ENABLED		0x1
+#define EMUL_NATIVE		0x2
+#define IPV6_FAITH		0x1d
+#define IPV6_OPTIONS		0x1
+#define IPV6_RTHDR_STRICT	0x1
+#define IPV6_SOCKOPT_RESERVED1	0x3
+#define SIOCGIFGENERIC		0xc020693a
+#define SIOCSIFGENERIC		0x80206939
+#define WALTSIG			0x4
+'
+
+includes_SunOS='
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <sys/mkdev.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <termios.h>
+#include <netinet/ip.h>
+#include <netinet/ip_mroute.h>
+'
+
+
+includes='
+#include <sys/types.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <sys/signal.h>
+#include <signal.h>
+#include <sys/resource.h>
+#include <time.h>
+'
+ccflags="$@"
+
+# Write go tool cgo -godefs input.
+(
+	echo package unix
+	echo
+	echo '/*'
+	indirect="includes_$(uname)"
+	echo "${!indirect} $includes"
+	echo '*/'
+	echo 'import "C"'
+	echo 'import "syscall"'
+	echo
+	echo 'const ('
+
+	# The gcc command line prints all the #defines
+	# it encounters while processing the input
+	echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
+	awk '
+		$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
+
+		$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next}  # 386 registers
+		$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
+		$2 ~ /^(SCM_SRCRT)$/ {next}
+		$2 ~ /^(MAP_FAILED)$/ {next}
+		$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.
+
+		$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
+		$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}
+
+		$2 !~ /^ECCAPBITS/ &&
+		$2 !~ /^ETH_/ &&
+		$2 !~ /^EPROC_/ &&
+		$2 !~ /^EQUIV_/ &&
+		$2 !~ /^EXPR_/ &&
+		$2 ~ /^E[A-Z0-9_]+$/ ||
+		$2 ~ /^B[0-9_]+$/ ||
+		$2 ~ /^(OLD|NEW)DEV$/ ||
+		$2 == "BOTHER" ||
+		$2 ~ /^CI?BAUD(EX)?$/ ||
+		$2 == "IBSHIFT" ||
+		$2 ~ /^V[A-Z0-9]+$/ ||
+		$2 ~ /^CS[A-Z0-9]/ ||
+		$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
+		$2 ~ /^IGN/ ||
+		$2 ~ /^IX(ON|ANY|OFF)$/ ||
+		$2 ~ /^IN(LCR|PCK)$/ ||
+		$2 !~ "X86_CR3_PCID_NOFLUSH" &&
+		$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
+		$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
+		$2 == "BRKINT" ||
+		$2 == "HUPCL" ||
+		$2 == "PENDIN" ||
+		$2 == "TOSTOP" ||
+		$2 == "XCASE" ||
+		$2 == "ALTWERASE" ||
+		$2 == "NOKERNINFO" ||
+		$2 ~ /^PAR/ ||
+		$2 ~ /^SIG[^_]/ ||
+		$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
+		$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
+		$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
+		$2 ~ /^O?XTABS$/ ||
+		$2 ~ /^TC[IO](ON|OFF)$/ ||
+		$2 ~ /^IN_/ ||
+		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
+		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
+		$2 ~ /^TP_STATUS_/ ||
+		$2 ~ /^FALLOC_/ ||
+		$2 == "ICMPV6_FILTER" ||
+		$2 == "SOMAXCONN" ||
+		$2 == "NAME_MAX" ||
+		$2 == "IFNAMSIZ" ||
+		$2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
+		$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
+		$2 ~ /^HW_MACHINE$/ ||
+		$2 ~ /^SYSCTL_VERS/ ||
+		$2 !~ "MNT_BITS" &&
+		$2 ~ /^(MS|MNT|UMOUNT)_/ ||
+		$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
+		$2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ ||
+		$2 ~ /^KEXEC_/ ||
+		$2 ~ /^LINUX_REBOOT_CMD_/ ||
+		$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
+		$2 ~ /^MODULE_INIT_/ ||
+		$2 !~ "NLA_TYPE_MASK" &&
+		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
+		$2 ~ /^SIOC/ ||
+		$2 ~ /^TIOC/ ||
+		$2 ~ /^TCGET/ ||
+		$2 ~ /^TCSET/ ||
+		$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
+		$2 !~ "RTF_BITS" &&
+		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
+		$2 ~ /^BIOC/ ||
+		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
+		$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
+		$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
+		$2 ~ /^CLONE_[A-Z_]+/ ||
+		$2 !~ /^(BPF_TIMEVAL)$/ &&
+		$2 ~ /^(BPF|DLT)_/ ||
+		$2 ~ /^CLOCK_/ ||
+		$2 ~ /^CAN_/ ||
+		$2 ~ /^CAP_/ ||
+		$2 ~ /^ALG_/ ||
+		$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
+		$2 ~ /^GRND_/ ||
+		$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
+		$2 ~ /^KEYCTL_/ ||
+		$2 ~ /^PERF_EVENT_IOC_/ ||
+		$2 ~ /^SECCOMP_MODE_/ ||
+		$2 ~ /^SPLICE_/ ||
+		$2 ~ /^SYNC_FILE_RANGE_/ ||
+		$2 !~ /^AUDIT_RECORD_MAGIC/ &&
+		$2 !~ /IOC_MAGIC/ &&
+		$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
+		$2 ~ /^(VM|VMADDR)_/ ||
+		$2 ~ /^IOCTL_VM_SOCKETS_/ ||
+		$2 ~ /^(TASKSTATS|TS)_/ ||
+		$2 ~ /^CGROUPSTATS_/ ||
+		$2 ~ /^GENL_/ ||
+		$2 ~ /^STATX_/ ||
+		$2 ~ /^RENAME/ ||
+		$2 ~ /^UBI_IOC[A-Z]/ ||
+		$2 ~ /^UTIME_/ ||
+		$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
+		$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
+		$2 ~ /^FSOPT_/ ||
+		$2 ~ /^WDIOC_/ ||
+		$2 ~ /^NFN/ ||
+		$2 ~ /^XDP_/ ||
+		$2 ~ /^(HDIO|WIN|SMART)_/ ||
+		$2 !~ "WMESGLEN" &&
+		$2 ~ /^W[A-Z0-9]+$/ ||
+		$2 ~/^PPPIOC/ ||
+		$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
+		$2 ~ /^__WCOREFLAG$/ {next}
+		$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
+
+		{next}
+	' | sort
+
+	echo ')'
+) >_const.go
+
+# Pull out the error names for later.
+errors=$(
+	echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
+	sort
+)
+
+# Pull out the signal names for later.
+signals=$(
+	echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
+	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
+	sort
+)
+
+# Again, writing regexps to a file.
+echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
+	sort >_error.grep
+echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
+	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
+	sort >_signal.grep
+
+echo '// mkerrors.sh' "$@"
+echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
+echo
+echo "// +build ${GOARCH},${GOOS}"
+echo
+go tool cgo -godefs -- "$@" _const.go >_error.out
+cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
+echo
+echo '// Errors'
+echo 'const ('
+cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
+echo ')'
+
+echo
+echo '// Signals'
+echo 'const ('
+cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
+echo ')'
+
+# Run C program to print error and syscall strings.
+(
+	echo -E "
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
+
+struct tuple {
+	int num;
+	const char *name;
+};
+
+struct tuple errors[] = {
+"
+	for i in $errors
+	do
+		echo -E '	{'$i', "'$i'" },'
+	done
+
+	echo -E "
+};
+
+struct tuple signals[] = {
+"
+	for i in $signals
+	do
+		echo -E '	{'$i', "'$i'" },'
+	done
+
+	# Use -E because on some systems bash builtin interprets \n itself.
+	echo -E '
+};
+
+static int
+tuplecmp(const void *a, const void *b)
+{
+	return ((struct tuple *)a)->num - ((struct tuple *)b)->num;
+}
+
+int
+main(void)
+{
+	int i, e;
+	char buf[1024], *p;
+
+	printf("\n\n// Error table\n");
+	printf("var errorList = [...]struct {\n");
+	printf("\tnum  syscall.Errno\n");
+	printf("\tname string\n");
+	printf("\tdesc string\n");
+	printf("} {\n");
+	qsort(errors, nelem(errors), sizeof errors[0], tuplecmp);
+	for(i=0; i<nelem(errors); i++) {
+		e = errors[i].num;
+		if(i > 0 && errors[i-1].num == e)
+			continue;
+		strcpy(buf, strerror(e));
+		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+			buf[0] += a - A;
+		printf("\t{ %d, \"%s\", \"%s\" },\n", e, errors[i].name, buf);
+	}
+	printf("}\n\n");
+
+	printf("\n\n// Signal table\n");
+	printf("var signalList = [...]struct {\n");
+	printf("\tnum  syscall.Signal\n");
+	printf("\tname string\n");
+	printf("\tdesc string\n");
+	printf("} {\n");
+	qsort(signals, nelem(signals), sizeof signals[0], tuplecmp);
+	for(i=0; i<nelem(signals); i++) {
+		e = signals[i].num;
+		if(i > 0 && signals[i-1].num == e)
+			continue;
+		strcpy(buf, strsignal(e));
+		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+			buf[0] += a - A;
+		// cut trailing : number.
+		p = strrchr(buf, ":"[0]);
+		if(p)
+			*p = '\0';
+		printf("\t{ %d, \"%s\", \"%s\" },\n", e, signals[i].name, buf);
+	}
+	printf("}\n\n");
+
+	return 0;
+}
+
+'
+) >_errors.c
+
+$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
diff --git a/vendor/golang.org/x/sys/unix/mkpost.go b/vendor/golang.org/x/sys/unix/mkpost.go
index 7e5c22c47..6d263cf15 100644
--- a/vendor/golang.org/x/sys/unix/mkpost.go
+++ b/vendor/golang.org/x/sys/unix/mkpost.go
@@ -46,6 +46,10 @@ func main() {
 	valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`)
 	b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}"))
 
+	// Intentionally export __fds_bits field in FdSet
+	fdSetRegex := regexp.MustCompile(`type (FdSet) struct {(\s+)X__fds_bits(\s+\S+\s+)}`)
+	b = fdSetRegex.ReplaceAll(b, []byte("type $1 struct {${2}Bits$3}"))
+
 	// If we have empty Ptrace structs, we should delete them. Only s390x emits
 	// nonempty Ptrace structs.
 	ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
@@ -65,6 +69,10 @@ func main() {
 	convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
 	b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
 
+	// Convert [1024]int8 to [1024]byte in Ptmget members
+	convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
+	b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
+
 	// Remove spare fields (e.g. in Statx_t)
 	spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
 	b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
diff --git a/vendor/golang.org/x/sys/unix/mksyscall.pl b/vendor/golang.org/x/sys/unix/mksyscall.pl
new file mode 100755
index 000000000..1f6b926f8
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksyscall.pl
@@ -0,0 +1,341 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_darwin.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+#	* The parameter lists must give a name for each argument.
+#	  This includes return parameters.
+#	* The parameter lists must give a type for each argument:
+#	  the (x, y, z int) shorthand is not allowed.
+#	* If the return parameter is an error number, it must be named errno.
+
+# A line beginning with //sysnb is like //sys, except that the
+# goroutine will not be suspended during the execution of the system
+# call.  This must only be used for system calls which can never
+# block, as otherwise the system call could cause all goroutines to
+# hang.
+
+use strict;
+
+my $cmdline = "mksyscall.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $plan9 = 0;
+my $openbsd = 0;
+my $netbsd = 0;
+my $dragonfly = 0;
+my $arm = 0; # 64-bit value should use (even, odd)-pair
+my $tags = "";  # build tags
+
+if($ARGV[0] eq "-b32") {
+	$_32bit = "big-endian";
+	shift;
+} elsif($ARGV[0] eq "-l32") {
+	$_32bit = "little-endian";
+	shift;
+}
+if($ARGV[0] eq "-plan9") {
+	$plan9 = 1;
+	shift;
+}
+if($ARGV[0] eq "-openbsd") {
+	$openbsd = 1;
+	shift;
+}
+if($ARGV[0] eq "-netbsd") {
+	$netbsd = 1;
+	shift;
+}
+if($ARGV[0] eq "-dragonfly") {
+	$dragonfly = 1;
+	shift;
+}
+if($ARGV[0] eq "-arm") {
+	$arm = 1;
+	shift;
+}
+if($ARGV[0] eq "-tags") {
+	shift;
+	$tags = $ARGV[0];
+	shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+	print STDERR "usage: mksyscall.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
+	exit 1;
+}
+
+# Check that we are using the new build system if we should
+if($ENV{'GOOS'} eq "linux" && $ENV{'GOARCH'} ne "sparc64") {
+	if($ENV{'GOLANG_SYS_BUILD'} ne "docker") {
+		print STDERR "In the new build system, mksyscall should not be called directly.\n";
+		print STDERR "See README.md\n";
+		exit 1;
+	}
+}
+
+
+sub parseparamlist($) {
+	my ($list) = @_;
+	$list =~ s/^\s*//;
+	$list =~ s/\s*$//;
+	if($list eq "") {
+		return ();
+	}
+	return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+	my ($p) = @_;
+	if($p !~ /^(\S*) (\S*)$/) {
+		print STDERR "$ARGV:$.: malformed parameter: $p\n";
+		$errors = 1;
+		return ("xx", "int");
+	}
+	return ($1, $2);
+}
+
+my $text = "";
+while(<>) {
+	chomp;
+	s/\s+/ /g;
+	s/^\s+//;
+	s/\s+$//;
+	my $nonblock = /^\/\/sysnb /;
+	next if !/^\/\/sys / && !$nonblock;
+
+	# Line must be of the form
+	#	func Open(path string, mode int, perm int) (fd int, errno error)
+	# Split into name, in params, out params.
+	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$/) {
+		print STDERR "$ARGV:$.: malformed //sys declaration\n";
+		$errors = 1;
+		next;
+	}
+	my ($func, $in, $out, $sysname) = ($2, $3, $4, $5);
+
+	# Split argument lists on comma.
+	my @in = parseparamlist($in);
+	my @out = parseparamlist($out);
+
+	# Try in vain to keep people from editing this file.
+	# The theory is that they jump into the middle of the file
+	# without reading the header.
+	$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+
+	# Go function header.
+	my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : "";
+	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl;
+
+	# Check if err return available
+	my $errvar = "";
+	foreach my $p (@out) {
+		my ($name, $type) = parseparam($p);
+		if($type eq "error") {
+			$errvar = $name;
+			last;
+		}
+	}
+
+	# Prepare arguments to Syscall.
+	my @args = ();
+	my $n = 0;
+	foreach my $p (@in) {
+		my ($name, $type) = parseparam($p);
+		if($type =~ /^\*/) {
+			push @args, "uintptr(unsafe.Pointer($name))";
+		} elsif($type eq "string" && $errvar ne "") {
+			$text .= "\tvar _p$n *byte\n";
+			$text .= "\t_p$n, $errvar = BytePtrFromString($name)\n";
+			$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type eq "string") {
+			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+			$text .= "\tvar _p$n *byte\n";
+			$text .= "\t_p$n, _ = BytePtrFromString($name)\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type =~ /^\[\](.*)/) {
+			# Convert slice into pointer, length.
+			# Have to be careful not to take address of &a[0] if len == 0:
+			# pass dummy pointer in that case.
+			# Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
+			$text .= "\tvar _p$n unsafe.Pointer\n";
+			$text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}";
+			$text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}";
+			$text .= "\n";
+			push @args, "uintptr(_p$n)", "uintptr(len($name))";
+			$n++;
+		} elsif($type eq "int64" && ($openbsd || $netbsd)) {
+			push @args, "0";
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name>>32)", "uintptr($name)";
+			} elsif($_32bit eq "little-endian") {
+				push @args, "uintptr($name)", "uintptr($name>>32)";
+			} else {
+				push @args, "uintptr($name)";
+			}
+		} elsif($type eq "int64" && $dragonfly) {
+			if ($func !~ /^extp(read|write)/i) {
+				push @args, "0";
+			}
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name>>32)", "uintptr($name)";
+			} elsif($_32bit eq "little-endian") {
+				push @args, "uintptr($name)", "uintptr($name>>32)";
+			} else {
+				push @args, "uintptr($name)";
+			}
+		} elsif($type eq "int64" && $_32bit ne "") {
+			if(@args % 2 && $arm) {
+				# arm abi specifies 64-bit argument uses
+				# (even, odd) pair
+				push @args, "0"
+			}
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name>>32)", "uintptr($name)";
+			} else {
+				push @args, "uintptr($name)", "uintptr($name>>32)";
+			}
+		} else {
+			push @args, "uintptr($name)";
+		}
+	}
+
+	# Determine which form to use; pad args with zeros.
+	my $asm = "Syscall";
+	if ($nonblock) {
+		if ($errvar eq "" && $ENV{'GOOS'} eq "linux") {
+			$asm = "RawSyscallNoError";
+		} else {
+			$asm = "RawSyscall";
+		}
+	} else {
+		if ($errvar eq "" && $ENV{'GOOS'} eq "linux") {
+			$asm = "SyscallNoError";
+		}
+	}
+	if(@args <= 3) {
+		while(@args < 3) {
+			push @args, "0";
+		}
+	} elsif(@args <= 6) {
+		$asm .= "6";
+		while(@args < 6) {
+			push @args, "0";
+		}
+	} elsif(@args <= 9) {
+		$asm .= "9";
+		while(@args < 9) {
+			push @args, "0";
+		}
+	} else {
+		print STDERR "$ARGV:$.: too many arguments to system call\n";
+	}
+
+	# System call number.
+	if($sysname eq "") {
+		$sysname = "SYS_$func";
+		$sysname =~ s/([a-z])([A-Z])/${1}_$2/g;	# turn FooBar into Foo_Bar
+		$sysname =~ y/a-z/A-Z/;
+	}
+
+	# Actual call.
+	my $args = join(', ', @args);
+	my $call = "$asm($sysname, $args)";
+
+	# Assign return values.
+	my $body = "";
+	my @ret = ("_", "_", "_");
+	my $do_errno = 0;
+	for(my $i=0; $i<@out; $i++) {
+		my $p = $out[$i];
+		my ($name, $type) = parseparam($p);
+		my $reg = "";
+		if($name eq "err" && !$plan9) {
+			$reg = "e1";
+			$ret[2] = $reg;
+			$do_errno = 1;
+		} elsif($name eq "err" && $plan9) {
+			$ret[0] = "r0";
+			$ret[2] = "e1";
+			next;
+		} else {
+			$reg = sprintf("r%d", $i);
+			$ret[$i] = $reg;
+		}
+		if($type eq "bool") {
+			$reg = "$reg != 0";
+		}
+		if($type eq "int64" && $_32bit ne "") {
+			# 64-bit number in r1:r0 or r0:r1.
+			if($i+2 > @out) {
+				print STDERR "$ARGV:$.: not enough registers for int64 return\n";
+			}
+			if($_32bit eq "big-endian") {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
+			} else {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
+			}
+			$ret[$i] = sprintf("r%d", $i);
+			$ret[$i+1] = sprintf("r%d", $i+1);
+		}
+		if($reg ne "e1" || $plan9) {
+			$body .= "\t$name = $type($reg)\n";
+		}
+	}
+	if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
+		$text .= "\t$call\n";
+	} else {
+		if ($errvar eq "" && $ENV{'GOOS'} eq "linux") {
+			# raw syscall without error on Linux, see golang.org/issue/22924
+			$text .= "\t$ret[0], $ret[1] := $call\n";
+		} else {
+			$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
+		}
+	}
+	$text .= $body;
+
+	if ($plan9 && $ret[2] eq "e1") {
+		$text .= "\tif int32(r0) == -1 {\n";
+		$text .= "\t\terr = e1\n";
+		$text .= "\t}\n";
+	} elsif ($do_errno) {
+		$text .= "\tif e1 != 0 {\n";
+		$text .= "\t\terr = errnoErr(e1)\n";
+		$text .= "\t}\n";
+	}
+	$text .= "\treturn\n";
+	$text .= "}\n\n";
+}
+
+chomp $text;
+chomp $text;
+
+if($errors) {
+	exit 1;
+}
+
+print <<EOF;
+// $cmdline
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $tags
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var _ syscall.Errno
+
+$text
+EOF
+exit 0;
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl
new file mode 100755
index 000000000..c44de8d31
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl
@@ -0,0 +1,384 @@
+#!/usr/bin/env perl
+# Copyright 2018 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_aix.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+#	* The parameter lists must give a name for each argument.
+#	  This includes return parameters.
+#	* The parameter lists must give a type for each argument:
+#	  the (x, y, z int) shorthand is not allowed.
+#	* If the return parameter is an error number, it must be named err.
+#	* If go func name needs to be different than its libc name,
+#	* or the function is not in libc, name could be specified
+#	* at the end, after "=" sign, like
+#	  //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
+
+use strict;
+
+my $cmdline = "mksyscall_aix_ppc.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $tags = "";  # build tags
+my $aix = 0;
+my $solaris = 0;
+
+binmode STDOUT;
+
+if($ARGV[0] eq "-b32") {
+	$_32bit = "big-endian";
+	shift;
+} elsif($ARGV[0] eq "-l32") {
+	$_32bit = "little-endian";
+	shift;
+}
+if($ARGV[0] eq "-aix") {
+	$aix = 1;
+	shift;
+}
+if($ARGV[0] eq "-tags") {
+	shift;
+	$tags = $ARGV[0];
+	shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+	print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
+	exit 1;
+}
+
+sub parseparamlist($) {
+	my ($list) = @_;
+	$list =~ s/^\s*//;
+	$list =~ s/\s*$//;
+	if($list eq "") {
+		return ();
+	}
+	return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+	my ($p) = @_;
+	if($p !~ /^(\S*) (\S*)$/) {
+		print STDERR "$ARGV:$.: malformed parameter: $p\n";
+		$errors = 1;
+		return ("xx", "int");
+	}
+	return ($1, $2);
+}
+
+my $package = "";
+my $text = "";
+my $c_extern = "/*\n#include <stdint.h>\n#include <stddef.h>\n";
+my @vars = ();
+while(<>) {
+	chomp;
+	s/\s+/ /g;
+	s/^\s+//;
+	s/\s+$//;
+	$package = $1 if !$package && /^package (\S+)$/;
+	my $nonblock = /^\/\/sysnb /;
+	next if !/^\/\/sys / && !$nonblock;
+
+	# Line must be of the form
+	# func Open(path string, mode int, perm int) (fd int, err error)
+	# Split into name, in params, out params.
+	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
+		print STDERR "$ARGV:$.: malformed //sys declaration\n";
+		$errors = 1;
+		next;
+	}
+	my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
+
+	# Split argument lists on comma.
+	my @in = parseparamlist($in);
+	my @out = parseparamlist($out);
+
+	$in = join(', ', @in);
+	$out = join(', ', @out);
+
+	# Try in vain to keep people from editing this file.
+	# The theory is that they jump into the middle of the file
+	# without reading the header.
+	$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+
+	# Check if value return, err return available
+	my $errvar = "";
+	my $retvar = "";
+	my $rettype = "";
+	foreach my $p (@out) {
+		my ($name, $type) = parseparam($p);
+		if($type eq "error") {
+			$errvar = $name;
+		} else {
+			$retvar = $name;
+			$rettype = $type;
+		}
+	}
+
+	# System call name.
+	#if($func ne "fcntl") {
+
+	if($sysname eq "") {
+		$sysname = "$func";
+	}
+
+	$sysname =~ s/([a-z])([A-Z])/${1}_$2/g;
+	$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
+
+	my $C_rettype = "";
+	if($rettype eq "unsafe.Pointer") {
+		$C_rettype = "uintptr_t";
+	} elsif($rettype eq "uintptr") {
+		$C_rettype = "uintptr_t";
+	} elsif($rettype =~ /^_/) {
+		$C_rettype = "uintptr_t";
+	} elsif($rettype eq "int") {
+		$C_rettype = "int";
+	} elsif($rettype eq "int32") {
+		$C_rettype = "int";
+	} elsif($rettype eq "int64") {
+		$C_rettype = "long long";
+	} elsif($rettype eq "uint32") {
+		$C_rettype = "unsigned int";
+	} elsif($rettype eq "uint64") {
+		$C_rettype = "unsigned long long";
+	} else {
+		$C_rettype = "int";
+	}
+	if($sysname eq "exit") {
+		$C_rettype = "void";
+	}
+
+	# Change types to c
+	my @c_in = ();
+	foreach my $p (@in) {
+		my ($name, $type) = parseparam($p);
+		if($type =~ /^\*/) {
+			push @c_in, "uintptr_t";
+			} elsif($type eq "string") {
+			push @c_in, "uintptr_t";
+		} elsif($type =~ /^\[\](.*)/) {
+			push @c_in, "uintptr_t", "size_t";
+		} elsif($type eq "unsafe.Pointer") {
+			push @c_in, "uintptr_t";
+		} elsif($type eq "uintptr") {
+			push @c_in, "uintptr_t";
+		} elsif($type =~ /^_/) {
+			push @c_in, "uintptr_t";
+		} elsif($type eq "int") {
+			push @c_in, "int";
+		} elsif($type eq "int32") {
+			push @c_in, "int";
+		} elsif($type eq "int64") {
+			push @c_in, "long long";
+		} elsif($type eq "uint32") {
+			push @c_in, "unsigned int";
+		} elsif($type eq "uint64") {
+			push @c_in, "unsigned long long";
+		} else {
+			push @c_in, "int";
+		}
+	}
+
+	if ($func ne "fcntl" && $func ne "FcntlInt" && $func ne "readlen" && $func ne "writelen") {
+		# Imports of system calls from libc
+		$c_extern .= "$C_rettype $sysname";
+		my $c_in = join(', ', @c_in);
+		$c_extern .= "($c_in);\n";
+	}
+
+	# So file name.
+	if($aix) {
+		if($modname eq "") {
+			$modname = "libc.a/shr_64.o";
+		} else {
+			print STDERR "$func: only syscall using libc are available\n";
+			$errors = 1;
+			next;
+		}
+	}
+
+	my $strconvfunc = "C.CString";
+	my $strconvtype = "*byte";
+
+	# Go function header.
+	if($out ne "") {
+		$out = " ($out)";
+	}
+	if($text ne "") {
+		$text .= "\n"
+	}
+
+	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ;
+
+	# Prepare arguments to call.
+	my @args = ();
+	my $n = 0;
+	my $arg_n = 0;
+	foreach my $p (@in) {
+		my ($name, $type) = parseparam($p);
+		if($type =~ /^\*/) {
+			push @args, "C.uintptr_t(uintptr(unsafe.Pointer($name)))";
+		} elsif($type eq "string" && $errvar ne "") {
+			$text .= "\t_p$n := uintptr(unsafe.Pointer($strconvfunc($name)))\n";
+			push @args, "C.uintptr_t(_p$n)";
+			$n++;
+		} elsif($type eq "string") {
+			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+			$text .= "\t_p$n := uintptr(unsafe.Pointer($strconvfunc($name)))\n";
+			push @args, "C.uintptr_t(_p$n)";
+			$n++;
+		} elsif($type =~ /^\[\](.*)/) {
+			# Convert slice into pointer, length.
+			# Have to be careful not to take address of &a[0] if len == 0:
+			# pass nil in that case.
+			$text .= "\tvar _p$n *$1\n";
+			$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
+			push @args, "C.uintptr_t(uintptr(unsafe.Pointer(_p$n)))";
+			$n++;
+			$text .= "\tvar _p$n int\n";
+			$text .= "\t_p$n = len($name)\n";
+			push @args, "C.size_t(_p$n)";
+			$n++;
+		} elsif($type eq "int64" && $_32bit ne "") {
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name >> 32)", "uintptr($name)";
+			} else {
+				push @args, "uintptr($name)", "uintptr($name >> 32)";
+			}
+			$n++;
+		} elsif($type eq "bool") {
+			$text .= "\tvar _p$n uint32\n";
+			$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
+			push @args, "_p$n";
+			$n++;
+		} elsif($type =~ /^_/) {
+			push @args, "C.uintptr_t(uintptr($name))";
+		} elsif($type eq "unsafe.Pointer") {
+			push @args, "C.uintptr_t(uintptr($name))";
+		} elsif($type eq "int") {
+			if (($arg_n == 2) && (($func eq "readlen") || ($func eq "writelen"))) {
+				push @args, "C.size_t($name)";
+			} elsif ($arg_n == 0 && $func eq "fcntl") {
+				push @args, "C.uintptr_t($name)";
+			} elsif (($arg_n == 2) && (($func eq "fcntl") || ($func eq "FcntlInt"))) {
+				push @args, "C.uintptr_t($name)";
+			} else {
+				push @args, "C.int($name)";
+			}
+		} elsif($type eq "int32") {
+			push @args, "C.int($name)";
+		} elsif($type eq "int64") {
+			push @args, "C.longlong($name)";
+		} elsif($type eq "uint32") {
+			push @args, "C.uint($name)";
+		} elsif($type eq "uint64") {
+			push @args, "C.ulonglong($name)";
+		} elsif($type eq "uintptr") {
+			push @args, "C.uintptr_t($name)";
+		} else {
+			push @args, "C.int($name)";
+		}
+		$arg_n++;
+	}
+	my $nargs = @args;
+
+
+	# Determine which form to use; pad args with zeros.
+	if ($nonblock) {
+	}
+
+	my $args = join(', ', @args);
+	my $call = "";
+	if ($sysname eq "exit") {
+		if ($errvar ne "") {
+			$call .= "er :=";
+		} else {
+			$call .= "";
+		}
+	}  elsif ($errvar ne "") {
+		$call .= "r0,er :=";
+	}  elsif ($retvar ne "") {
+		$call .= "r0,_ :=";
+	}  else {
+		$call .= ""
+	}
+	$call .= "C.$sysname($args)";
+
+	# Assign return values.
+	my $body = "";
+	my $failexpr = "";
+
+	for(my $i=0; $i<@out; $i++) {
+		my $p = $out[$i];
+		my ($name, $type) = parseparam($p);
+		my $reg = "";
+		if($name eq "err") {
+			$reg = "e1";
+		} else {
+			$reg = "r0";
+		}
+		if($reg ne "e1" ) {
+						$body .= "\t$name = $type($reg)\n";
+		}
+	}
+
+	# verify return
+	if ($sysname ne "exit" && $errvar ne "") {
+		if ($C_rettype =~ /^uintptr/) {
+			$body .= "\tif \(uintptr\(r0\) ==\^uintptr\(0\) && er != nil\) {\n";
+			$body .= "\t\t$errvar = er\n";
+			$body .= "\t}\n";
+		} else {
+			$body .= "\tif \(r0 ==-1 && er != nil\) {\n";
+			$body .= "\t\t$errvar = er\n";
+			$body .= "\t}\n";
+		}
+	} elsif ($errvar ne "") {
+		$body .= "\tif \(er != nil\) {\n";
+		$body .= "\t\t$errvar = er\n";
+		$body .= "\t}\n";
+	}
+
+	$text .= "\t$call\n";
+	$text .= $body;
+
+	$text .= "\treturn\n";
+	$text .= "}\n";
+}
+
+if($errors) {
+	exit 1;
+}
+
+print <<EOF;
+// $cmdline
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $tags
+
+package $package
+
+
+$c_extern
+*/
+import "C"
+import (
+	"unsafe"
+)
+
+
+EOF
+
+print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
+
+chomp($_=<<EOF);
+
+$text
+EOF
+print $_;
+exit 0;
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl
new file mode 100755
index 000000000..53df26bb9
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl
@@ -0,0 +1,579 @@
+#!/usr/bin/env perl
+# Copyright 2018 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_aix.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+#	* The parameter lists must give a name for each argument.
+#	  This includes return parameters.
+#	* The parameter lists must give a type for each argument:
+#	  the (x, y, z int) shorthand is not allowed.
+#	* If the return parameter is an error number, it must be named err.
+#	* If go func name needs to be different than its libc name,
+#	* or the function is not in libc, name could be specified
+#	* at the end, after "=" sign, like
+#	  //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
+
+# This program will generate three files and handle both gc and gccgo implementation:
+#   - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation)
+#   - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6
+#   - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type.
+
+# The generated code looks like this
+#
+# zsyscall_aix_ppc64.go
+# func asyscall(...) (n int, err error) {
+#	  // Pointer Creation
+#	  r1, e1 := callasyscall(...)
+#	  // Type Conversion
+#	  // Error Handler
+#	  return
+# }
+#
+# zsyscall_aix_ppc64_gc.go
+# //go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o"
+# //go:linkname libc_asyscall libc_asyscall
+# var asyscall syscallFunc
+#
+# func callasyscall(...) (r1 uintptr, e1 Errno) {
+#	  r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
+#	  return
+# }
+#
+# zsyscall_aix_ppc64_ggcgo.go
+# /*
+#  int asyscall(...)
+#
+# */
+# import "C"
+#
+# func callasyscall(...) (r1 uintptr, e1 Errno) {
+#	  r1 = uintptr(C.asyscall(...))
+#	  e1 = syscall.GetErrno()
+#	  return
+# }
+
+
+
+use strict;
+
+my $cmdline = "mksyscall_aix_ppc64.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $tags = "";  # build tags
+my $aix = 0;
+my $solaris = 0;
+
+binmode STDOUT;
+
+if($ARGV[0] eq "-b32") {
+	$_32bit = "big-endian";
+	shift;
+} elsif($ARGV[0] eq "-l32") {
+	$_32bit = "little-endian";
+	shift;
+}
+if($ARGV[0] eq "-aix") {
+	$aix = 1;
+	shift;
+}
+if($ARGV[0] eq "-tags") {
+	shift;
+	$tags = $ARGV[0];
+	shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+	print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
+	exit 1;
+}
+
+sub parseparamlist($) {
+	my ($list) = @_;
+	$list =~ s/^\s*//;
+	$list =~ s/\s*$//;
+	if($list eq "") {
+		return ();
+	}
+	return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+	my ($p) = @_;
+	if($p !~ /^(\S*) (\S*)$/) {
+		print STDERR "$ARGV:$.: malformed parameter: $p\n";
+		$errors = 1;
+		return ("xx", "int");
+	}
+	return ($1, $2);
+}
+
+my $package = "";
+# GCCGO
+my $textgccgo = "";
+my $c_extern = "/*\n#include <stdint.h>\n";
+# GC
+my $textgc = "";
+my $dynimports = "";
+my $linknames = "";
+my @vars = ();
+# COMMUN
+my $textcommon = "";
+
+while(<>) {
+	chomp;
+	s/\s+/ /g;
+	s/^\s+//;
+	s/\s+$//;
+	$package = $1 if !$package && /^package (\S+)$/;
+	my $nonblock = /^\/\/sysnb /;
+	next if !/^\/\/sys / && !$nonblock;
+
+	# Line must be of the form
+	# func Open(path string, mode int, perm int) (fd int, err error)
+	# Split into name, in params, out params.
+	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
+		print STDERR "$ARGV:$.: malformed //sys declaration\n";
+		$errors = 1;
+		next;
+	}
+	my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
+
+	# Split argument lists on comma.
+	my @in = parseparamlist($in);
+	my @out = parseparamlist($out);
+
+	$in = join(', ', @in);
+	$out = join(', ', @out);
+
+	if($sysname eq "") {
+		$sysname = "$func";
+	}
+
+	my $onlyCommon = 0;
+	if ($func eq "readlen" || $func eq "writelen" || $func eq "FcntlInt" || $func eq "FcntlFlock") {
+		# This function call another syscall which is already implemented.
+		# Therefore, the gc and gccgo part must not be generated.
+		$onlyCommon = 1
+	}
+
+	# Try in vain to keep people from editing this file.
+	# The theory is that they jump into the middle of the file
+	# without reading the header.
+
+	$textcommon .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+	if (!$onlyCommon) {
+		$textgccgo .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+		$textgc .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+	}
+
+
+	# Check if value return, err return available
+	my $errvar = "";
+	my $retvar = "";
+	my $rettype = "";
+	foreach my $p (@out) {
+		my ($name, $type) = parseparam($p);
+		if($type eq "error") {
+			$errvar = $name;
+		} else {
+			$retvar = $name;
+			$rettype = $type;
+		}
+	}
+
+
+	$sysname =~ s/([a-z])([A-Z])/${1}_$2/g;
+	$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
+
+	# GCCGO Prototype return type
+	my $C_rettype = "";
+	if($rettype eq "unsafe.Pointer") {
+		$C_rettype = "uintptr_t";
+	} elsif($rettype eq "uintptr") {
+		$C_rettype = "uintptr_t";
+	} elsif($rettype =~ /^_/) {
+		$C_rettype = "uintptr_t";
+	} elsif($rettype eq "int") {
+		$C_rettype = "int";
+	} elsif($rettype eq "int32") {
+		$C_rettype = "int";
+	} elsif($rettype eq "int64") {
+		$C_rettype = "long long";
+	} elsif($rettype eq "uint32") {
+		$C_rettype = "unsigned int";
+	} elsif($rettype eq "uint64") {
+		$C_rettype = "unsigned long long";
+	} else {
+		$C_rettype = "int";
+	}
+	if($sysname eq "exit") {
+		$C_rettype = "void";
+	}
+
+	# GCCGO Prototype arguments type
+	my @c_in = ();
+	foreach my $i (0 .. $#in) {
+		my ($name, $type) = parseparam($in[$i]);
+		if($type =~ /^\*/) {
+			push @c_in, "uintptr_t";
+			} elsif($type eq "string") {
+			push @c_in, "uintptr_t";
+		} elsif($type =~ /^\[\](.*)/) {
+			push @c_in, "uintptr_t", "size_t";
+		} elsif($type eq "unsafe.Pointer") {
+			push @c_in, "uintptr_t";
+		} elsif($type eq "uintptr") {
+			push @c_in, "uintptr_t";
+		} elsif($type =~ /^_/) {
+			push @c_in, "uintptr_t";
+		} elsif($type eq "int") {
+			if (($i == 0 || $i == 2) && $func eq "fcntl"){
+				# These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
+				push @c_in, "uintptr_t";
+			} else {
+				push @c_in, "int";
+			}
+		} elsif($type eq "int32") {
+			push @c_in, "int";
+		} elsif($type eq "int64") {
+			push @c_in, "long long";
+		} elsif($type eq "uint32") {
+			push @c_in, "unsigned int";
+		} elsif($type eq "uint64") {
+			push @c_in, "unsigned long long";
+		} else {
+			push @c_in, "int";
+		}
+	}
+
+	if (!$onlyCommon){
+		# GCCGO Prototype Generation
+		# Imports of system calls from libc
+		$c_extern .= "$C_rettype $sysname";
+		my $c_in = join(', ', @c_in);
+		$c_extern .= "($c_in);\n";
+	}
+
+	# GC Library name
+	if($modname eq "") {
+		$modname = "libc.a/shr_64.o";
+	} else {
+		print STDERR "$func: only syscall using libc are available\n";
+		$errors = 1;
+		next;
+	}
+	my $sysvarname = "libc_${sysname}";
+
+	if (!$onlyCommon){
+		# GC Runtime import of function to allow cross-platform builds.
+		$dynimports .= "//go:cgo_import_dynamic ${sysvarname} ${sysname} \"$modname\"\n";
+		# GC Link symbol to proc address variable.
+		$linknames .= "//go:linkname ${sysvarname} ${sysvarname}\n";
+		# GC Library proc address variable.
+		push @vars, $sysvarname;
+	}
+
+	my $strconvfunc ="BytePtrFromString";
+	my $strconvtype = "*byte";
+
+	# Go function header.
+	if($out ne "") {
+		$out = " ($out)";
+	}
+	if($textcommon ne "") {
+		$textcommon .= "\n"
+	}
+
+	$textcommon .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ;
+
+	# Prepare arguments to call.
+	my @argscommun = (); # Arguments in the commun part
+	my @argscall = ();   # Arguments for call prototype
+	my @argsgc = ();     # Arguments for gc call (with syscall6)
+	my @argsgccgo = ();  # Arguments for gccgo call (with C.name_of_syscall)
+	my $n = 0;
+	my $arg_n = 0;
+	foreach my $p (@in) {
+		my ($name, $type) = parseparam($p);
+		if($type =~ /^\*/) {
+			push @argscommun, "uintptr(unsafe.Pointer($name))";
+			push @argscall, "$name uintptr";
+			push @argsgc, "$name";
+			push @argsgccgo, "C.uintptr_t($name)";
+		} elsif($type eq "string" && $errvar ne "") {
+			$textcommon .= "\tvar _p$n $strconvtype\n";
+			$textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n";
+			$textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+
+			push @argscommun, "uintptr(unsafe.Pointer(_p$n))";
+			push @argscall, "_p$n uintptr ";
+			push @argsgc, "_p$n";
+			push @argsgccgo, "C.uintptr_t(_p$n)";
+			$n++;
+		} elsif($type eq "string") {
+			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+			$textcommon .= "\tvar _p$n $strconvtype\n";
+			$textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n";
+			$textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+
+			push @argscommun, "uintptr(unsafe.Pointer(_p$n))";
+			push @argscall, "_p$n uintptr";
+			push @argsgc, "_p$n";
+			push @argsgccgo, "C.uintptr_t(_p$n)";
+			$n++;
+		} elsif($type =~ /^\[\](.*)/) {
+			# Convert slice into pointer, length.
+			# Have to be careful not to take address of &a[0] if len == 0:
+			# pass nil in that case.
+			$textcommon .= "\tvar _p$n *$1\n";
+			$textcommon .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
+			push @argscommun, "uintptr(unsafe.Pointer(_p$n))", "len($name)";
+			push @argscall, "_p$n uintptr", "_lenp$n int";
+			push @argsgc, "_p$n", "uintptr(_lenp$n)";
+			push @argsgccgo, "C.uintptr_t(_p$n)", "C.size_t(_lenp$n)";
+			$n++;
+		} elsif($type eq "int64" && $_32bit ne "") {
+			print STDERR "$ARGV:$.: $func uses int64 with 32 bits mode. Case not yet implemented\n";
+			# if($_32bit eq "big-endian") {
+			# 	push @args, "uintptr($name >> 32)", "uintptr($name)";
+			# } else {
+			# 	push @args, "uintptr($name)", "uintptr($name >> 32)";
+			# }
+			# $n++;
+		} elsif($type eq "bool") {
+			print STDERR "$ARGV:$.: $func uses bool. Case not yet implemented\n";
+			# $text .= "\tvar _p$n uint32\n";
+			# $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
+			# push @args, "_p$n";
+			# $n++;
+		} elsif($type =~ /^_/ ||$type eq "unsafe.Pointer") {
+			push @argscommun, "uintptr($name)";
+			push @argscall, "$name uintptr";
+			push @argsgc, "$name";
+			push @argsgccgo, "C.uintptr_t($name)";
+		} elsif($type eq "int") {
+			if (($arg_n == 0 || $arg_n == 2) && ($func eq "fcntl" || $func eq "FcntlInt" || $func eq "FcntlFlock")) {
+				# These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
+				push @argscommun, "uintptr($name)";
+				push @argscall, "$name uintptr";
+				push @argsgc, "$name";
+				push @argsgccgo, "C.uintptr_t($name)";
+			} else {
+				push @argscommun, "$name";
+				push @argscall, "$name int";
+				push @argsgc, "uintptr($name)";
+				push @argsgccgo, "C.int($name)";
+			}
+		} elsif($type eq "int32") {
+			push @argscommun, "$name";
+			push @argscall, "$name int32";
+			push @argsgc, "uintptr($name)";
+			push @argsgccgo, "C.int($name)";
+		} elsif($type eq "int64") {
+			push @argscommun, "$name";
+			push @argscall, "$name int64";
+			push @argsgc, "uintptr($name)";
+			push @argsgccgo, "C.longlong($name)";
+		} elsif($type eq "uint32") {
+			push @argscommun, "$name";
+			push @argscall, "$name uint32";
+			push @argsgc, "uintptr($name)";
+			push @argsgccgo, "C.uint($name)";
+		} elsif($type eq "uint64") {
+			push @argscommun, "$name";
+			push @argscall, "$name uint64";
+			push @argsgc, "uintptr($name)";
+			push @argsgccgo, "C.ulonglong($name)";
+		} elsif($type eq "uintptr") {
+			push @argscommun, "$name";
+			push @argscall, "$name uintptr";
+			push @argsgc, "$name";
+			push @argsgccgo, "C.uintptr_t($name)";
+		} else {
+			push @argscommun, "int($name)";
+			push @argscall, "$name int";
+			push @argsgc, "uintptr($name)";
+			push @argsgccgo, "C.int($name)";
+		}
+		$arg_n++;
+	}
+	my $nargs = @argsgc;
+
+	# COMMUN function generation
+	my $argscommun = join(', ', @argscommun);
+	my $callcommun = "call$sysname($argscommun)";
+	my @ret = ("_", "_");
+	my $body = "";
+	my $do_errno = 0;
+	for(my $i=0; $i<@out; $i++) {
+		my $p = $out[$i];
+		my ($name, $type) = parseparam($p);
+		my $reg = "";
+		if($name eq "err") {
+			$reg = "e1";
+			$ret[1] = $reg;
+			$do_errno = 1;
+		} else {
+			$reg = "r0";
+			$ret[0] = $reg;
+		}
+		if($type eq "bool") {
+			$reg = "$reg != 0";
+		}
+		if($reg ne "e1") {
+			$body .= "\t$name = $type($reg)\n";
+		}
+	}
+	if ($ret[0] eq "_"  && $ret[1] eq "_") {
+		$textcommon .= "\t$callcommun\n";
+	} else {
+		$textcommon .= "\t$ret[0], $ret[1] := $callcommun\n";
+	}
+	$textcommon .= $body;
+
+	if ($do_errno) {
+		$textcommon .= "\tif e1 != 0 {\n";
+		$textcommon .= "\t\terr = errnoErr(e1)\n";
+		$textcommon .= "\t}\n";
+	}
+	$textcommon .= "\treturn\n";
+	$textcommon .= "}\n";
+
+	if ($onlyCommon){
+		next
+	}
+	# CALL Prototype
+	my $callProto = sprintf "func call%s(%s) (r1 uintptr, e1 Errno) {\n", $sysname, join(', ', @argscall);
+
+	# GC function generation
+	my $asm = "syscall6";
+	if ($nonblock) {
+		$asm = "rawSyscall6";
+	}
+
+	if(@argsgc <= 6) {
+		while(@argsgc < 6) {
+			push @argsgc, "0";
+		}
+	} else {
+		print STDERR "$ARGV:$.: too many arguments to system call\n";
+	}
+	my $argsgc = join(', ', @argsgc);
+	my $callgc = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $argsgc)";
+
+	$textgc .= $callProto;
+	$textgc .= "\tr1, _, e1 = $callgc\n";
+	$textgc .= "\treturn\n}\n";
+
+	# GCCGO function generation
+	my $argsgccgo = join(', ', @argsgccgo);
+	my $callgccgo = "C.$sysname($argsgccgo)";
+	$textgccgo .= $callProto;
+	$textgccgo .= "\tr1 = uintptr($callgccgo)\n";
+	$textgccgo .= "\te1 = syscall.GetErrno()\n";
+	$textgccgo .= "\treturn\n}\n";
+}
+
+if($errors) {
+	exit 1;
+}
+
+# Print zsyscall_aix_ppc64.go
+open(my $fcommun, '>', 'zsyscall_aix_ppc64.go');
+my $tofcommun = <<EOF;
+// $cmdline
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $tags
+
+package $package
+
+import (
+	"unsafe"
+)
+
+EOF
+
+$tofcommun .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
+
+$tofcommun .=<<EOF;
+
+$textcommon
+EOF
+print $fcommun $tofcommun;
+
+
+# Print zsyscall_aix_ppc64_gc.go
+open(my $fgc, '>', 'zsyscall_aix_ppc64_gc.go');
+my $tofgc = <<EOF;
+// $cmdline
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $tags
+// +build !gccgo
+
+package $package
+
+import (
+	"unsafe"
+)
+
+
+EOF
+
+$tofgc .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
+
+my $vardecls = "\t" . join(",\n\t", @vars);
+$vardecls .= " syscallFunc";
+
+$tofgc .=<<EOF;
+$dynimports
+$linknames
+type syscallFunc uintptr
+
+var (
+$vardecls
+)
+
+// Implemented in runtime/syscall_aix.go.
+func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+$textgc
+EOF
+print $fgc $tofgc;
+
+# Print zsyscall_aix_ppc64_gc.go
+open(my $fgccgo, '>', 'zsyscall_aix_ppc64_gccgo.go');
+my $tofgccgo = <<EOF;
+// $cmdline
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $tags
+// +build gccgo
+
+package $package
+
+
+$c_extern
+*/
+import "C"
+import (
+	"syscall"
+)
+
+
+EOF
+
+$tofgccgo .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
+
+$tofgccgo .=<<EOF;
+
+$textgccgo
+EOF
+print $fgccgo $tofgccgo;
+exit 0;
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl b/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl
new file mode 100755
index 000000000..a354df5a6
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl
@@ -0,0 +1,294 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_solaris.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+#	* The parameter lists must give a name for each argument.
+#	  This includes return parameters.
+#	* The parameter lists must give a type for each argument:
+#	  the (x, y, z int) shorthand is not allowed.
+#	* If the return parameter is an error number, it must be named err.
+#	* If go func name needs to be different than its libc name,
+#	* or the function is not in libc, name could be specified
+#	* at the end, after "=" sign, like
+#	  //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
+
+use strict;
+
+my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $tags = "";  # build tags
+
+binmode STDOUT;
+
+if($ARGV[0] eq "-b32") {
+	$_32bit = "big-endian";
+	shift;
+} elsif($ARGV[0] eq "-l32") {
+	$_32bit = "little-endian";
+	shift;
+}
+if($ARGV[0] eq "-tags") {
+	shift;
+	$tags = $ARGV[0];
+	shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+	print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
+	exit 1;
+}
+
+sub parseparamlist($) {
+	my ($list) = @_;
+	$list =~ s/^\s*//;
+	$list =~ s/\s*$//;
+	if($list eq "") {
+		return ();
+	}
+	return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+	my ($p) = @_;
+	if($p !~ /^(\S*) (\S*)$/) {
+		print STDERR "$ARGV:$.: malformed parameter: $p\n";
+		$errors = 1;
+		return ("xx", "int");
+	}
+	return ($1, $2);
+}
+
+my $package = "";
+my $text = "";
+my $dynimports = "";
+my $linknames = "";
+my @vars = ();
+while(<>) {
+	chomp;
+	s/\s+/ /g;
+	s/^\s+//;
+	s/\s+$//;
+	$package = $1 if !$package && /^package (\S+)$/;
+	my $nonblock = /^\/\/sysnb /;
+	next if !/^\/\/sys / && !$nonblock;
+
+	# Line must be of the form
+	#	func Open(path string, mode int, perm int) (fd int, err error)
+	# Split into name, in params, out params.
+	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
+		print STDERR "$ARGV:$.: malformed //sys declaration\n";
+		$errors = 1;
+		next;
+	}
+	my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
+
+	# Split argument lists on comma.
+	my @in = parseparamlist($in);
+	my @out = parseparamlist($out);
+
+	# Try in vain to keep people from editing this file.
+	# The theory is that they jump into the middle of the file
+	# without reading the header.
+	$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+
+	# So file name.
+	if($modname eq "") {
+		$modname = "libc";
+	}
+
+	# System call name.
+	if($sysname eq "") {
+		$sysname = "$func";
+	}
+
+	# System call pointer variable name.
+	my $sysvarname = "proc$sysname";
+
+	my $strconvfunc = "BytePtrFromString";
+	my $strconvtype = "*byte";
+
+	$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
+
+	# Runtime import of function to allow cross-platform builds.
+	$dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n";
+	# Link symbol to proc address variable.
+	$linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n";
+	# Library proc address variable.
+	push @vars, $sysvarname;
+
+	# Go function header.
+	$out = join(', ', @out);
+	if($out ne "") {
+		$out = " ($out)";
+	}
+	if($text ne "") {
+		$text .= "\n"
+	}
+	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;
+
+	# Check if err return available
+	my $errvar = "";
+	foreach my $p (@out) {
+		my ($name, $type) = parseparam($p);
+		if($type eq "error") {
+			$errvar = $name;
+			last;
+		}
+	}
+
+	# Prepare arguments to Syscall.
+	my @args = ();
+	my $n = 0;
+	foreach my $p (@in) {
+		my ($name, $type) = parseparam($p);
+		if($type =~ /^\*/) {
+			push @args, "uintptr(unsafe.Pointer($name))";
+		} elsif($type eq "string" && $errvar ne "") {
+			$text .= "\tvar _p$n $strconvtype\n";
+			$text .= "\t_p$n, $errvar = $strconvfunc($name)\n";
+			$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type eq "string") {
+			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+			$text .= "\tvar _p$n $strconvtype\n";
+			$text .= "\t_p$n, _ = $strconvfunc($name)\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type =~ /^\[\](.*)/) {
+			# Convert slice into pointer, length.
+			# Have to be careful not to take address of &a[0] if len == 0:
+			# pass nil in that case.
+			$text .= "\tvar _p$n *$1\n";
+			$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
+			$n++;
+		} elsif($type eq "int64" && $_32bit ne "") {
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name >> 32)", "uintptr($name)";
+			} else {
+				push @args, "uintptr($name)", "uintptr($name >> 32)";
+			}
+		} elsif($type eq "bool") {
+ 			$text .= "\tvar _p$n uint32\n";
+			$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
+			push @args, "uintptr(_p$n)";
+			$n++;
+		} else {
+			push @args, "uintptr($name)";
+		}
+	}
+	my $nargs = @args;
+
+	# Determine which form to use; pad args with zeros.
+	my $asm = "sysvicall6";
+	if ($nonblock) {
+		$asm = "rawSysvicall6";
+	}
+	if(@args <= 6) {
+		while(@args < 6) {
+			push @args, "0";
+		}
+	} else {
+		print STDERR "$ARGV:$.: too many arguments to system call\n";
+	}
+
+	# Actual call.
+	my $args = join(', ', @args);
+	my $call = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $args)";
+
+	# Assign return values.
+	my $body = "";
+	my $failexpr = "";
+	my @ret = ("_", "_", "_");
+	my @pout= ();
+	my $do_errno = 0;
+	for(my $i=0; $i<@out; $i++) {
+		my $p = $out[$i];
+		my ($name, $type) = parseparam($p);
+		my $reg = "";
+		if($name eq "err") {
+			$reg = "e1";
+			$ret[2] = $reg;
+			$do_errno = 1;
+		} else {
+			$reg = sprintf("r%d", $i);
+			$ret[$i] = $reg;
+		}
+		if($type eq "bool") {
+			$reg = "$reg != 0";
+		}
+		if($type eq "int64" && $_32bit ne "") {
+			# 64-bit number in r1:r0 or r0:r1.
+			if($i+2 > @out) {
+				print STDERR "$ARGV:$.: not enough registers for int64 return\n";
+			}
+			if($_32bit eq "big-endian") {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
+			} else {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
+			}
+			$ret[$i] = sprintf("r%d", $i);
+			$ret[$i+1] = sprintf("r%d", $i+1);
+		}
+		if($reg ne "e1") {
+			$body .= "\t$name = $type($reg)\n";
+		}
+	}
+	if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
+		$text .= "\t$call\n";
+	} else {
+		$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
+	}
+	$text .= $body;
+
+	if ($do_errno) {
+		$text .= "\tif e1 != 0 {\n";
+		$text .= "\t\terr = e1\n";
+		$text .= "\t}\n";
+	}
+	$text .= "\treturn\n";
+	$text .= "}\n";
+}
+
+if($errors) {
+	exit 1;
+}
+
+print <<EOF;
+// $cmdline
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $tags
+
+package $package
+
+import (
+	"syscall"
+	"unsafe"
+)
+EOF
+
+print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
+
+my $vardecls = "\t" . join(",\n\t", @vars);
+$vardecls .= " syscallFunc";
+
+chomp($_=<<EOF);
+
+$dynimports
+$linknames
+var (
+$vardecls
+)
+
+$text
+EOF
+print $_;
+exit 0;
diff --git a/vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl b/vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
new file mode 100755
index 000000000..20632e146
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
@@ -0,0 +1,265 @@
+#!/usr/bin/env perl
+
+# Copyright 2011 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+#
+# Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
+#
+# Build a MIB with each entry being an array containing the level, type and
+# a hash that will contain additional entries if the current entry is a node.
+# We then walk this MIB and create a flattened sysctl name to OID hash.
+#
+
+use strict;
+
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+	print STDERR "GOARCH or GOOS not defined in environment\n";
+	exit 1;
+}
+
+my $debug = 0;
+my %ctls = ();
+
+my @headers = qw (
+	sys/sysctl.h
+	sys/socket.h
+	sys/tty.h
+	sys/malloc.h
+	sys/mount.h
+	sys/namei.h
+	sys/sem.h
+	sys/shm.h
+	sys/vmmeter.h
+	uvm/uvmexp.h
+	uvm/uvm_param.h
+	uvm/uvm_swap_encrypt.h
+	ddb/db_var.h
+	net/if.h
+	net/if_pfsync.h
+	net/pipex.h
+	netinet/in.h
+	netinet/icmp_var.h
+	netinet/igmp_var.h
+	netinet/ip_ah.h
+	netinet/ip_carp.h
+	netinet/ip_divert.h
+	netinet/ip_esp.h
+	netinet/ip_ether.h
+	netinet/ip_gre.h
+	netinet/ip_ipcomp.h
+	netinet/ip_ipip.h
+	netinet/pim_var.h
+	netinet/tcp_var.h
+	netinet/udp_var.h
+	netinet6/in6.h
+	netinet6/ip6_divert.h
+	netinet6/pim6_var.h
+	netinet/icmp6.h
+	netmpls/mpls.h
+);
+
+my @ctls = qw (
+	kern
+	vm
+	fs
+	net
+	#debug				# Special handling required
+	hw
+	#machdep			# Arch specific
+	user
+	ddb
+	#vfs				# Special handling required
+	fs.posix
+	kern.forkstat
+	kern.intrcnt
+	kern.malloc
+	kern.nchstats
+	kern.seminfo
+	kern.shminfo
+	kern.timecounter
+	kern.tty
+	kern.watchdog
+	net.bpf
+	net.ifq
+	net.inet
+	net.inet.ah
+	net.inet.carp
+	net.inet.divert
+	net.inet.esp
+	net.inet.etherip
+	net.inet.gre
+	net.inet.icmp
+	net.inet.igmp
+	net.inet.ip
+	net.inet.ip.ifq
+	net.inet.ipcomp
+	net.inet.ipip
+	net.inet.mobileip
+	net.inet.pfsync
+	net.inet.pim
+	net.inet.tcp
+	net.inet.udp
+	net.inet6
+	net.inet6.divert
+	net.inet6.ip6
+	net.inet6.icmp6
+	net.inet6.pim6
+	net.inet6.tcp6
+	net.inet6.udp6
+	net.mpls
+	net.mpls.ifq
+	net.key
+	net.pflow
+	net.pfsync
+	net.pipex
+	net.rt
+	vm.swapencrypt
+	#vfsgenctl			# Special handling required
+);
+
+# Node name "fixups"
+my %ctl_map = (
+	"ipproto" => "net.inet",
+	"net.inet.ipproto" => "net.inet",
+	"net.inet6.ipv6proto" => "net.inet6",
+	"net.inet6.ipv6" => "net.inet6.ip6",
+	"net.inet.icmpv6" => "net.inet6.icmp6",
+	"net.inet6.divert6" => "net.inet6.divert",
+	"net.inet6.tcp6" => "net.inet.tcp",
+	"net.inet6.udp6" => "net.inet.udp",
+	"mpls" => "net.mpls",
+	"swpenc" => "vm.swapencrypt"
+);
+
+# Node mappings
+my %node_map = (
+	"net.inet.ip.ifq" => "net.ifq",
+	"net.inet.pfsync" => "net.pfsync",
+	"net.mpls.ifq" => "net.ifq"
+);
+
+my $ctlname;
+my %mib = ();
+my %sysctl = ();
+my $node;
+
+sub debug() {
+	print STDERR "$_[0]\n" if $debug;
+}
+
+# Walk the MIB and build a sysctl name to OID mapping.
+sub build_sysctl() {
+	my ($node, $name, $oid) = @_;
+	my %node = %{$node};
+	my @oid = @{$oid};
+
+	foreach my $key (sort keys %node) {
+		my @node = @{$node{$key}};
+		my $nodename = $name.($name ne '' ? '.' : '').$key;
+		my @nodeoid = (@oid, $node[0]);
+		if ($node[1] eq 'CTLTYPE_NODE') {
+			if (exists $node_map{$nodename}) {
+				$node = \%mib;
+				$ctlname = $node_map{$nodename};
+				foreach my $part (split /\./, $ctlname) {
+					$node = \%{@{$$node{$part}}[2]};
+				}
+			} else {
+				$node = $node[2];
+			}
+			&build_sysctl($node, $nodename, \@nodeoid);
+		} elsif ($node[1] ne '') {
+			$sysctl{$nodename} = \@nodeoid;
+		}
+	}
+}
+
+foreach my $ctl (@ctls) {
+	$ctls{$ctl} = $ctl;
+}
+
+# Build MIB
+foreach my $header (@headers) {
+	&debug("Processing $header...");
+	open HEADER, "/usr/include/$header" ||
+	    print STDERR "Failed to open $header\n";
+	while (<HEADER>) {
+		if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ ||
+		    $_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ ||
+		    $_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) {
+			if ($1 eq 'CTL_NAMES') {
+				# Top level.
+				$node = \%mib;
+			} else {
+				# Node.
+				my $nodename = lc($2);
+				if ($header =~ /^netinet\//) {
+					$ctlname = "net.inet.$nodename";
+				} elsif ($header =~ /^netinet6\//) {
+					$ctlname = "net.inet6.$nodename";
+				} elsif ($header =~ /^net\//) {
+					$ctlname = "net.$nodename";
+				} else {
+					$ctlname = "$nodename";
+					$ctlname =~ s/^(fs|net|kern)_/$1\./;
+				}
+				if (exists $ctl_map{$ctlname}) {
+					$ctlname = $ctl_map{$ctlname};
+				}
+				if (not exists $ctls{$ctlname}) {
+					&debug("Ignoring $ctlname...");
+					next;
+				}
+
+				# Walk down from the top of the MIB.
+				$node = \%mib;
+				foreach my $part (split /\./, $ctlname) {
+					if (not exists $$node{$part}) {
+						&debug("Missing node $part");
+						$$node{$part} = [ 0, '', {} ];
+					}
+					$node = \%{@{$$node{$part}}[2]};
+				}
+			}
+
+			# Populate current node with entries.
+			my $i = -1;
+			while (defined($_) && $_ !~ /^}/) {
+				$_ = <HEADER>;
+				$i++ if $_ =~ /{.*}/;
+				next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/;
+				$$node{$1} = [ $i, $2, {} ];
+			}
+		}
+	}
+	close HEADER;
+}
+
+&build_sysctl(\%mib, "", []);
+
+print <<EOF;
+// mksysctl_openbsd.pl
+// Code generated by the command above; DO NOT EDIT.
+
+// +build $ENV{'GOARCH'},$ENV{'GOOS'}
+
+package unix;
+
+type mibentry struct {
+	ctlname string
+	ctloid []_C_int
+}
+
+var sysctlMib = []mibentry {
+EOF
+
+foreach my $name (sort keys %sysctl) {
+	my @oid = @{$sysctl{$name}};
+	print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n";
+}
+
+print <<EOF;
+}
+EOF
diff --git a/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl b/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl
new file mode 100755
index 000000000..5453c53b1
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl
@@ -0,0 +1,39 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+#
+# Generate system call table for Darwin from sys/syscall.h
+
+use strict;
+
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+	print STDERR "GOARCH or GOOS not defined in environment\n";
+	exit 1;
+}
+
+my $command = "mksysnum_darwin.pl " . join(' ', @ARGV);
+
+print <<EOF;
+// $command
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $ENV{'GOARCH'},$ENV{'GOOS'}
+
+package unix
+
+const (
+EOF
+
+while(<>){
+	if(/^#define\s+SYS_(\w+)\s+([0-9]+)/){
+		my $name = $1;
+		my $num = $2;
+		$name =~ y/a-z/A-Z/;
+		print "	SYS_$name = $num;"
+	}
+}
+
+print <<EOF;
+)
+EOF
diff --git a/vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl b/vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl
new file mode 100755
index 000000000..6804f4121
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+#
+# Generate system call table for DragonFly from master list
+# (for example, /usr/src/sys/kern/syscalls.master).
+
+use strict;
+
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+	print STDERR "GOARCH or GOOS not defined in environment\n";
+	exit 1;
+}
+
+my $command = "mksysnum_dragonfly.pl " . join(' ', @ARGV);
+
+print <<EOF;
+// $command
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $ENV{'GOARCH'},$ENV{'GOOS'}
+
+package unix
+
+const (
+EOF
+
+while(<>){
+	if(/^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$/){
+		my $num = $1;
+		my $proto = $2;
+		my $name = "SYS_$3";
+		$name =~ y/a-z/A-Z/;
+
+		# There are multiple entries for enosys and nosys, so comment them out.
+		if($name =~ /^SYS_E?NOSYS$/){
+			$name = "// $name";
+		}
+		if($name eq 'SYS_SYS_EXIT'){
+			$name = 'SYS_EXIT';
+		}
+
+		print "	$name = $num;  // $proto\n";
+	}
+}
+
+print <<EOF;
+)
+EOF
diff --git a/vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl b/vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl
new file mode 100755
index 000000000..198993d09
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+#
+# Generate system call table for FreeBSD from master list
+# (for example, /usr/src/sys/kern/syscalls.master).
+
+use strict;
+
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+	print STDERR "GOARCH or GOOS not defined in environment\n";
+	exit 1;
+}
+
+my $command = "mksysnum_freebsd.pl " . join(' ', @ARGV);
+
+print <<EOF;
+// $command
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $ENV{'GOARCH'},$ENV{'GOOS'}
+
+package unix
+
+const (
+EOF
+
+while(<>){
+	if(/^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$/){
+		my $num = $1;
+		my $proto = $2;
+		my $name = "SYS_$3";
+		$name =~ y/a-z/A-Z/;
+
+		# There are multiple entries for enosys and nosys, so comment them out.
+		if($name =~ /^SYS_E?NOSYS$/){
+			$name = "// $name";
+		}
+		if($name eq 'SYS_SYS_EXIT'){
+			$name = 'SYS_EXIT';
+		}
+
+		print "	$name = $num;  // $proto\n";
+	}
+}
+
+print <<EOF;
+)
+EOF
diff --git a/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl b/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl
new file mode 100755
index 000000000..85988b140
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+#
+# Generate system call table for OpenBSD from master list
+# (for example, /usr/src/sys/kern/syscalls.master).
+
+use strict;
+
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+	print STDERR "GOARCH or GOOS not defined in environment\n";
+	exit 1;
+}
+
+my $command = "mksysnum_netbsd.pl " . join(' ', @ARGV);
+
+print <<EOF;
+// $command
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $ENV{'GOARCH'},$ENV{'GOOS'}
+
+package unix
+
+const (
+EOF
+
+my $line = '';
+while(<>){
+	if($line =~ /^(.*)\\$/) {
+		# Handle continuation
+		$line = $1;
+		$_ =~ s/^\s+//;
+		$line .= $_;
+	} else {
+		# New line
+		$line = $_;
+	}
+	next if $line =~ /\\$/;
+	if($line =~ /^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$/) {
+		my $num = $1;
+		my $proto = $6;
+		my $compat = $8;
+		my $name = "$7_$9";
+
+		$name = "$7_$11" if $11 ne '';
+		$name =~ y/a-z/A-Z/;
+
+		if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') {
+			print "	$name = $num;  // $proto\n";
+		}
+	}
+}
+
+print <<EOF;
+)
+EOF
diff --git a/vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl b/vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl
new file mode 100755
index 000000000..84edf60ca
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+#
+# Generate system call table for OpenBSD from master list
+# (for example, /usr/src/sys/kern/syscalls.master).
+
+use strict;
+
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+	print STDERR "GOARCH or GOOS not defined in environment\n";
+	exit 1;
+}
+
+my $command = "mksysnum_openbsd.pl " . join(' ', @ARGV);
+
+print <<EOF;
+// $command
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build $ENV{'GOARCH'},$ENV{'GOOS'}
+
+package unix
+
+const (
+EOF
+
+while(<>){
+	if(/^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$/){
+		my $num = $1;
+		my $proto = $3;
+		my $name = $4;
+		$name =~ y/a-z/A-Z/;
+
+		# There are multiple entries for enosys and nosys, so comment them out.
+		if($name =~ /^SYS_E?NOSYS$/){
+			$name = "// $name";
+		}
+		if($name eq 'SYS_SYS_EXIT'){
+			$name = 'SYS_EXIT';
+		}
+
+		print "	$name = $num;  // $proto\n";
+	}
+}
+
+print <<EOF;
+)
+EOF
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 84aa8ea03..466b2576d 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -12,6 +12,8 @@
 package unix
 
 import (
+	"encoding/binary"
+	"net"
 	"syscall"
 	"unsafe"
 )
@@ -55,6 +57,15 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
 // ioctl itself should not be exposed directly, but additional get/set
 // functions for specific types are permissible.
 
+// IoctlSetPointerInt performs an ioctl operation which sets an
+// integer value on fd, using the specified request number. The ioctl
+// argument is called with a pointer to the integer value, rather than
+// passing the integer value directly.
+func IoctlSetPointerInt(fd int, req uint, value int) error {
+	v := int32(value)
+	return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
+}
+
 // IoctlSetInt performs an ioctl operation which sets an integer value
 // on fd, using the specified request number.
 func IoctlSetInt(fd int, req uint, value int) error {
@@ -710,6 +721,51 @@ func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil
 }
 
+// This constant mirrors the #define of PX_PROTO_OE in
+// linux/if_pppox.h. We're defining this by hand here instead of
+// autogenerating through mkerrors.sh because including
+// linux/if_pppox.h causes some declaration conflicts with other
+// includes (linux/if_pppox.h includes linux/in.h, which conflicts
+// with netinet/in.h). Given that we only need a single zero constant
+// out of that file, it's cleaner to just define it by hand here.
+const px_proto_oe = 0
+
+type SockaddrPPPoE struct {
+	SID    uint16
+	Remote net.HardwareAddr
+	Dev    string
+	raw    RawSockaddrPPPoX
+}
+
+func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if len(sa.Remote) != 6 {
+		return nil, 0, EINVAL
+	}
+	if len(sa.Dev) > IFNAMSIZ-1 {
+		return nil, 0, EINVAL
+	}
+
+	*(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX
+	// This next field is in host-endian byte order. We can't use the
+	// same unsafe pointer cast as above, because this value is not
+	// 32-bit aligned and some architectures don't allow unaligned
+	// access.
+	//
+	// However, the value of px_proto_oe is 0, so we can use
+	// encoding/binary helpers to write the bytes without worrying
+	// about the ordering.
+	binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe)
+	// This field is deliberately big-endian, unlike the previous
+	// one. The kernel expects SID to be in network byte order.
+	binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
+	copy(sa.raw[8:14], sa.Remote)
+	for i := 14; i < 14+IFNAMSIZ; i++ {
+		sa.raw[i] = 0
+	}
+	copy(sa.raw[14:], sa.Dev)
+	return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
+}
+
 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
 	switch rsa.Addr.Family {
 	case AF_NETLINK:
@@ -820,6 +876,22 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
 			SharedUmemFD: pp.Shared_umem_fd,
 		}
 		return sa, nil
+	case AF_PPPOX:
+		pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))
+		if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {
+			return nil, EINVAL
+		}
+		sa := &SockaddrPPPoE{
+			SID:    binary.BigEndian.Uint16(pp[6:8]),
+			Remote: net.HardwareAddr(pp[8:14]),
+		}
+		for i := 14; i < 14+IFNAMSIZ; i++ {
+			if pp[i] == 0 {
+				sa.Dev = string(pp[14:i])
+				break
+			}
+		}
+		return sa, nil
 	}
 	return nil, EAFNOSUPPORT
 }
diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
index b711aca82..059327a36 100644
--- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
@@ -13,6 +13,7 @@
 package unix
 
 import (
+	"runtime"
 	"syscall"
 	"unsafe"
 )
@@ -190,6 +191,13 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 	return &value, err
 }
 
+func IoctlGetPtmget(fd int, req uint) (*Ptmget, error) {
+	var value Ptmget
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	runtime.KeepAlive(value)
+	return &value, err
+}
+
 func Uname(uname *Utsname) error {
 	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
 	n := unsafe.Sizeof(uname.Sysname)
diff --git a/vendor/golang.org/x/sys/unix/syscall_unix_gc.go b/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
index 4cb8e8edf..1c70d1b69 100644
--- a/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
+++ b/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
-// +build !gccgo
+// +build !gccgo,!ppc64le,!ppc64
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go
new file mode 100644
index 000000000..86dc765ab
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go
@@ -0,0 +1,24 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build ppc64le ppc64
+// +build !gccgo
+
+package unix
+
+import "syscall"
+
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+	return syscall.Syscall(trap, a1, a2, a3)
+}
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+	return syscall.Syscall6(trap, a1, a2, a3, a4, a5, a6)
+}
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+	return syscall.RawSyscall(trap, a1, a2, a3)
+}
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+	return syscall.RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
+}
diff --git a/vendor/golang.org/x/sys/unix/types_freebsd.go b/vendor/golang.org/x/sys/unix/types_freebsd.go
index 8421ccf1c..747079895 100644
--- a/vendor/golang.org/x/sys/unix/types_freebsd.go
+++ b/vendor/golang.org/x/sys/unix/types_freebsd.go
@@ -26,7 +26,7 @@ package unix
 #include <termios.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <sys/capability.h>
+#include <sys/capsicum.h>
 #include <sys/event.h>
 #include <sys/mman.h>
 #include <sys/mount.h>
diff --git a/vendor/golang.org/x/sys/unix/types_netbsd.go b/vendor/golang.org/x/sys/unix/types_netbsd.go
index 1edbf1ba7..2dd4f9542 100644
--- a/vendor/golang.org/x/sys/unix/types_netbsd.go
+++ b/vendor/golang.org/x/sys/unix/types_netbsd.go
@@ -248,6 +248,8 @@ type Termios C.struct_termios
 
 type Winsize C.struct_winsize
 
+type Ptmget C.struct_ptmget
+
 // fchmodat-like syscalls.
 
 const (
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index 673152b94..db3c31ef8 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -1293,6 +1293,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x40042406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x2405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x4004743d
+	PPPIOCATTCHAN                        = 0x40047438
+	PPPIOCCONNECT                        = 0x4004743a
+	PPPIOCDETACH                         = 0x4004743c
+	PPPIOCDISCONN                        = 0x7439
+	PPPIOCGASYNCMAP                      = 0x80047458
+	PPPIOCGCHAN                          = 0x80047437
+	PPPIOCGDEBUG                         = 0x80047441
+	PPPIOCGFLAGS                         = 0x8004745a
+	PPPIOCGIDLE                          = 0x8008743f
+	PPPIOCGL2TPSTATS                     = 0x80487436
+	PPPIOCGMRU                           = 0x80047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x80047455
+	PPPIOCGUNIT                          = 0x80047456
+	PPPIOCGXASYNCMAP                     = 0x80207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x40087446
+	PPPIOCSASYNCMAP                      = 0x40047457
+	PPPIOCSCOMPRESS                      = 0x400c744d
+	PPPIOCSDEBUG                         = 0x40047440
+	PPPIOCSFLAGS                         = 0x40047459
+	PPPIOCSMAXCID                        = 0x40047451
+	PPPIOCSMRRU                          = 0x4004743b
+	PPPIOCSMRU                           = 0x40047452
+	PPPIOCSNPMODE                        = 0x4008744b
+	PPPIOCSPASS                          = 0x40087447
+	PPPIOCSRASYNCMAP                     = 0x40047454
+	PPPIOCSXASYNCMAP                     = 0x4020744f
+	PPPIOCXFERUNIT                       = 0x744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1696,6 +1726,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1751,6 +1782,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index 5735bcf3c..4785835b6 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -1293,6 +1293,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x40082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x2405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x4004743d
+	PPPIOCATTCHAN                        = 0x40047438
+	PPPIOCCONNECT                        = 0x4004743a
+	PPPIOCDETACH                         = 0x4004743c
+	PPPIOCDISCONN                        = 0x7439
+	PPPIOCGASYNCMAP                      = 0x80047458
+	PPPIOCGCHAN                          = 0x80047437
+	PPPIOCGDEBUG                         = 0x80047441
+	PPPIOCGFLAGS                         = 0x8004745a
+	PPPIOCGIDLE                          = 0x8010743f
+	PPPIOCGL2TPSTATS                     = 0x80487436
+	PPPIOCGMRU                           = 0x80047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x80047455
+	PPPIOCGUNIT                          = 0x80047456
+	PPPIOCGXASYNCMAP                     = 0x80207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x40107446
+	PPPIOCSASYNCMAP                      = 0x40047457
+	PPPIOCSCOMPRESS                      = 0x4010744d
+	PPPIOCSDEBUG                         = 0x40047440
+	PPPIOCSFLAGS                         = 0x40047459
+	PPPIOCSMAXCID                        = 0x40047451
+	PPPIOCSMRRU                          = 0x4004743b
+	PPPIOCSMRU                           = 0x40047452
+	PPPIOCSNPMODE                        = 0x4008744b
+	PPPIOCSPASS                          = 0x40107447
+	PPPIOCSRASYNCMAP                     = 0x40047454
+	PPPIOCSXASYNCMAP                     = 0x4020744f
+	PPPIOCXFERUNIT                       = 0x744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1697,6 +1727,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1752,6 +1783,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
index d8e8442e5..5e902423a 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
@@ -1291,6 +1291,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x40042406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x2405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x4004743d
+	PPPIOCATTCHAN                        = 0x40047438
+	PPPIOCCONNECT                        = 0x4004743a
+	PPPIOCDETACH                         = 0x4004743c
+	PPPIOCDISCONN                        = 0x7439
+	PPPIOCGASYNCMAP                      = 0x80047458
+	PPPIOCGCHAN                          = 0x80047437
+	PPPIOCGDEBUG                         = 0x80047441
+	PPPIOCGFLAGS                         = 0x8004745a
+	PPPIOCGIDLE                          = 0x8008743f
+	PPPIOCGL2TPSTATS                     = 0x80487436
+	PPPIOCGMRU                           = 0x80047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x80047455
+	PPPIOCGUNIT                          = 0x80047456
+	PPPIOCGXASYNCMAP                     = 0x80207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x40087446
+	PPPIOCSASYNCMAP                      = 0x40047457
+	PPPIOCSCOMPRESS                      = 0x400c744d
+	PPPIOCSDEBUG                         = 0x40047440
+	PPPIOCSFLAGS                         = 0x40047459
+	PPPIOCSMAXCID                        = 0x40047451
+	PPPIOCSMRRU                          = 0x4004743b
+	PPPIOCSMRU                           = 0x40047452
+	PPPIOCSNPMODE                        = 0x4008744b
+	PPPIOCSPASS                          = 0x40087447
+	PPPIOCSRASYNCMAP                     = 0x40047454
+	PPPIOCSXASYNCMAP                     = 0x4020744f
+	PPPIOCXFERUNIT                       = 0x744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1703,6 +1733,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1758,6 +1789,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index 5d79b789b..ebe9d8b41 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -1294,6 +1294,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x40082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x2405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x4004743d
+	PPPIOCATTCHAN                        = 0x40047438
+	PPPIOCCONNECT                        = 0x4004743a
+	PPPIOCDETACH                         = 0x4004743c
+	PPPIOCDISCONN                        = 0x7439
+	PPPIOCGASYNCMAP                      = 0x80047458
+	PPPIOCGCHAN                          = 0x80047437
+	PPPIOCGDEBUG                         = 0x80047441
+	PPPIOCGFLAGS                         = 0x8004745a
+	PPPIOCGIDLE                          = 0x8010743f
+	PPPIOCGL2TPSTATS                     = 0x80487436
+	PPPIOCGMRU                           = 0x80047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x80047455
+	PPPIOCGUNIT                          = 0x80047456
+	PPPIOCGXASYNCMAP                     = 0x80207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x40107446
+	PPPIOCSASYNCMAP                      = 0x40047457
+	PPPIOCSCOMPRESS                      = 0x4010744d
+	PPPIOCSDEBUG                         = 0x40047440
+	PPPIOCSFLAGS                         = 0x40047459
+	PPPIOCSMAXCID                        = 0x40047451
+	PPPIOCSMRRU                          = 0x4004743b
+	PPPIOCSMRU                           = 0x40047452
+	PPPIOCSNPMODE                        = 0x4008744b
+	PPPIOCSPASS                          = 0x40107447
+	PPPIOCSRASYNCMAP                     = 0x40047454
+	PPPIOCSXASYNCMAP                     = 0x4020744f
+	PPPIOCXFERUNIT                       = 0x744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1687,6 +1717,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1742,6 +1773,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
index 3c91615c8..d467d211b 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
@@ -1291,6 +1291,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x80042406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x20002405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x8004743d
+	PPPIOCATTCHAN                        = 0x80047438
+	PPPIOCCONNECT                        = 0x8004743a
+	PPPIOCDETACH                         = 0x8004743c
+	PPPIOCDISCONN                        = 0x20007439
+	PPPIOCGASYNCMAP                      = 0x40047458
+	PPPIOCGCHAN                          = 0x40047437
+	PPPIOCGDEBUG                         = 0x40047441
+	PPPIOCGFLAGS                         = 0x4004745a
+	PPPIOCGIDLE                          = 0x4008743f
+	PPPIOCGL2TPSTATS                     = 0x40487436
+	PPPIOCGMRU                           = 0x40047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x40047455
+	PPPIOCGUNIT                          = 0x40047456
+	PPPIOCGXASYNCMAP                     = 0x40207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x80087446
+	PPPIOCSASYNCMAP                      = 0x80047457
+	PPPIOCSCOMPRESS                      = 0x800c744d
+	PPPIOCSDEBUG                         = 0x80047440
+	PPPIOCSFLAGS                         = 0x80047459
+	PPPIOCSMAXCID                        = 0x80047451
+	PPPIOCSMRRU                          = 0x8004743b
+	PPPIOCSMRU                           = 0x80047452
+	PPPIOCSNPMODE                        = 0x8008744b
+	PPPIOCSPASS                          = 0x80087447
+	PPPIOCSRASYNCMAP                     = 0x80047454
+	PPPIOCSXASYNCMAP                     = 0x8020744f
+	PPPIOCXFERUNIT                       = 0x2000744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1696,6 +1726,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1751,6 +1782,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
index e1f86c1cd..9c293ed13 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
@@ -1291,6 +1291,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x80082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x20002405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x8004743d
+	PPPIOCATTCHAN                        = 0x80047438
+	PPPIOCCONNECT                        = 0x8004743a
+	PPPIOCDETACH                         = 0x8004743c
+	PPPIOCDISCONN                        = 0x20007439
+	PPPIOCGASYNCMAP                      = 0x40047458
+	PPPIOCGCHAN                          = 0x40047437
+	PPPIOCGDEBUG                         = 0x40047441
+	PPPIOCGFLAGS                         = 0x4004745a
+	PPPIOCGIDLE                          = 0x4010743f
+	PPPIOCGL2TPSTATS                     = 0x40487436
+	PPPIOCGMRU                           = 0x40047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x40047455
+	PPPIOCGUNIT                          = 0x40047456
+	PPPIOCGXASYNCMAP                     = 0x40207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x80107446
+	PPPIOCSASYNCMAP                      = 0x80047457
+	PPPIOCSCOMPRESS                      = 0x8010744d
+	PPPIOCSDEBUG                         = 0x80047440
+	PPPIOCSFLAGS                         = 0x80047459
+	PPPIOCSMAXCID                        = 0x80047451
+	PPPIOCSMRRU                          = 0x8004743b
+	PPPIOCSMRU                           = 0x80047452
+	PPPIOCSNPMODE                        = 0x8008744b
+	PPPIOCSPASS                          = 0x80107447
+	PPPIOCSRASYNCMAP                     = 0x80047454
+	PPPIOCSXASYNCMAP                     = 0x8020744f
+	PPPIOCXFERUNIT                       = 0x2000744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1696,6 +1726,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1751,6 +1782,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
index d09e3b68b..e2162508c 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
@@ -1291,6 +1291,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x80082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x20002405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x8004743d
+	PPPIOCATTCHAN                        = 0x80047438
+	PPPIOCCONNECT                        = 0x8004743a
+	PPPIOCDETACH                         = 0x8004743c
+	PPPIOCDISCONN                        = 0x20007439
+	PPPIOCGASYNCMAP                      = 0x40047458
+	PPPIOCGCHAN                          = 0x40047437
+	PPPIOCGDEBUG                         = 0x40047441
+	PPPIOCGFLAGS                         = 0x4004745a
+	PPPIOCGIDLE                          = 0x4010743f
+	PPPIOCGL2TPSTATS                     = 0x40487436
+	PPPIOCGMRU                           = 0x40047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x40047455
+	PPPIOCGUNIT                          = 0x40047456
+	PPPIOCGXASYNCMAP                     = 0x40207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x80107446
+	PPPIOCSASYNCMAP                      = 0x80047457
+	PPPIOCSCOMPRESS                      = 0x8010744d
+	PPPIOCSDEBUG                         = 0x80047440
+	PPPIOCSFLAGS                         = 0x80047459
+	PPPIOCSMAXCID                        = 0x80047451
+	PPPIOCSMRRU                          = 0x8004743b
+	PPPIOCSMRU                           = 0x80047452
+	PPPIOCSNPMODE                        = 0x8008744b
+	PPPIOCSPASS                          = 0x80107447
+	PPPIOCSRASYNCMAP                     = 0x80047454
+	PPPIOCSXASYNCMAP                     = 0x8020744f
+	PPPIOCXFERUNIT                       = 0x2000744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1696,6 +1726,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1751,6 +1782,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
index f78108dfb..836c0c654 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
@@ -1291,6 +1291,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x80042406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x20002405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x8004743d
+	PPPIOCATTCHAN                        = 0x80047438
+	PPPIOCCONNECT                        = 0x8004743a
+	PPPIOCDETACH                         = 0x8004743c
+	PPPIOCDISCONN                        = 0x20007439
+	PPPIOCGASYNCMAP                      = 0x40047458
+	PPPIOCGCHAN                          = 0x40047437
+	PPPIOCGDEBUG                         = 0x40047441
+	PPPIOCGFLAGS                         = 0x4004745a
+	PPPIOCGIDLE                          = 0x4008743f
+	PPPIOCGL2TPSTATS                     = 0x40487436
+	PPPIOCGMRU                           = 0x40047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x40047455
+	PPPIOCGUNIT                          = 0x40047456
+	PPPIOCGXASYNCMAP                     = 0x40207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x80087446
+	PPPIOCSASYNCMAP                      = 0x80047457
+	PPPIOCSCOMPRESS                      = 0x800c744d
+	PPPIOCSDEBUG                         = 0x80047440
+	PPPIOCSFLAGS                         = 0x80047459
+	PPPIOCSMAXCID                        = 0x80047451
+	PPPIOCSMRRU                          = 0x8004743b
+	PPPIOCSMRU                           = 0x80047452
+	PPPIOCSNPMODE                        = 0x8008744b
+	PPPIOCSPASS                          = 0x80087447
+	PPPIOCSRASYNCMAP                     = 0x80047454
+	PPPIOCSXASYNCMAP                     = 0x8020744f
+	PPPIOCXFERUNIT                       = 0x2000744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1696,6 +1726,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1751,6 +1782,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
index 8da57a99c..7ca618431 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
@@ -1292,6 +1292,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x80082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x20002405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x8004743d
+	PPPIOCATTCHAN                        = 0x80047438
+	PPPIOCCONNECT                        = 0x8004743a
+	PPPIOCDETACH                         = 0x8004743c
+	PPPIOCDISCONN                        = 0x20007439
+	PPPIOCGASYNCMAP                      = 0x40047458
+	PPPIOCGCHAN                          = 0x40047437
+	PPPIOCGDEBUG                         = 0x40047441
+	PPPIOCGFLAGS                         = 0x4004745a
+	PPPIOCGIDLE                          = 0x4010743f
+	PPPIOCGL2TPSTATS                     = 0x40487436
+	PPPIOCGMRU                           = 0x40047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x40047455
+	PPPIOCGUNIT                          = 0x40047456
+	PPPIOCGXASYNCMAP                     = 0x40207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x80107446
+	PPPIOCSASYNCMAP                      = 0x80047457
+	PPPIOCSCOMPRESS                      = 0x8010744d
+	PPPIOCSDEBUG                         = 0x80047440
+	PPPIOCSFLAGS                         = 0x80047459
+	PPPIOCSMAXCID                        = 0x80047451
+	PPPIOCSMRRU                          = 0x8004743b
+	PPPIOCSMRU                           = 0x80047452
+	PPPIOCSNPMODE                        = 0x8008744b
+	PPPIOCSPASS                          = 0x80107447
+	PPPIOCSRASYNCMAP                     = 0x80047454
+	PPPIOCSXASYNCMAP                     = 0x8020744f
+	PPPIOCXFERUNIT                       = 0x2000744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1752,6 +1782,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1807,6 +1838,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
index 1832c0a7c..839ac214c 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
@@ -1292,6 +1292,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x80082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x20002405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x8004743d
+	PPPIOCATTCHAN                        = 0x80047438
+	PPPIOCCONNECT                        = 0x8004743a
+	PPPIOCDETACH                         = 0x8004743c
+	PPPIOCDISCONN                        = 0x20007439
+	PPPIOCGASYNCMAP                      = 0x40047458
+	PPPIOCGCHAN                          = 0x40047437
+	PPPIOCGDEBUG                         = 0x40047441
+	PPPIOCGFLAGS                         = 0x4004745a
+	PPPIOCGIDLE                          = 0x4010743f
+	PPPIOCGL2TPSTATS                     = 0x40487436
+	PPPIOCGMRU                           = 0x40047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x40047455
+	PPPIOCGUNIT                          = 0x40047456
+	PPPIOCGXASYNCMAP                     = 0x40207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x80107446
+	PPPIOCSASYNCMAP                      = 0x80047457
+	PPPIOCSCOMPRESS                      = 0x8010744d
+	PPPIOCSDEBUG                         = 0x80047440
+	PPPIOCSFLAGS                         = 0x80047459
+	PPPIOCSMAXCID                        = 0x80047451
+	PPPIOCSMRRU                          = 0x8004743b
+	PPPIOCSMRU                           = 0x80047452
+	PPPIOCSNPMODE                        = 0x8008744b
+	PPPIOCSPASS                          = 0x80107447
+	PPPIOCSRASYNCMAP                     = 0x80047454
+	PPPIOCSXASYNCMAP                     = 0x8020744f
+	PPPIOCXFERUNIT                       = 0x2000744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1752,6 +1782,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1807,6 +1838,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
index c6bd4efff..a747aa1b7 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
@@ -1291,6 +1291,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x40082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x2405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x4004743d
+	PPPIOCATTCHAN                        = 0x40047438
+	PPPIOCCONNECT                        = 0x4004743a
+	PPPIOCDETACH                         = 0x4004743c
+	PPPIOCDISCONN                        = 0x7439
+	PPPIOCGASYNCMAP                      = 0x80047458
+	PPPIOCGCHAN                          = 0x80047437
+	PPPIOCGDEBUG                         = 0x80047441
+	PPPIOCGFLAGS                         = 0x8004745a
+	PPPIOCGIDLE                          = 0x8010743f
+	PPPIOCGL2TPSTATS                     = 0x80487436
+	PPPIOCGMRU                           = 0x80047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x80047455
+	PPPIOCGUNIT                          = 0x80047456
+	PPPIOCGXASYNCMAP                     = 0x80207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x40107446
+	PPPIOCSASYNCMAP                      = 0x40047457
+	PPPIOCSCOMPRESS                      = 0x4010744d
+	PPPIOCSDEBUG                         = 0x40047440
+	PPPIOCSFLAGS                         = 0x40047459
+	PPPIOCSMAXCID                        = 0x40047451
+	PPPIOCSMRRU                          = 0x4004743b
+	PPPIOCSMRU                           = 0x40047452
+	PPPIOCSNPMODE                        = 0x4008744b
+	PPPIOCSPASS                          = 0x40107447
+	PPPIOCSRASYNCMAP                     = 0x40047454
+	PPPIOCSXASYNCMAP                     = 0x4020744f
+	PPPIOCXFERUNIT                       = 0x744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1684,6 +1714,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1739,6 +1770,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
index 8cdf353dc..96aff5083 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
@@ -1291,6 +1291,36 @@ const (
 	PERF_EVENT_IOC_SET_FILTER            = 0x40082406
 	PERF_EVENT_IOC_SET_OUTPUT            = 0x2405
 	PIPEFS_MAGIC                         = 0x50495045
+	PPPIOCATTACH                         = 0x4004743d
+	PPPIOCATTCHAN                        = 0x40047438
+	PPPIOCCONNECT                        = 0x4004743a
+	PPPIOCDETACH                         = 0x4004743c
+	PPPIOCDISCONN                        = 0x7439
+	PPPIOCGASYNCMAP                      = 0x80047458
+	PPPIOCGCHAN                          = 0x80047437
+	PPPIOCGDEBUG                         = 0x80047441
+	PPPIOCGFLAGS                         = 0x8004745a
+	PPPIOCGIDLE                          = 0x8010743f
+	PPPIOCGL2TPSTATS                     = 0x80487436
+	PPPIOCGMRU                           = 0x80047453
+	PPPIOCGNPMODE                        = 0xc008744c
+	PPPIOCGRASYNCMAP                     = 0x80047455
+	PPPIOCGUNIT                          = 0x80047456
+	PPPIOCGXASYNCMAP                     = 0x80207450
+	PPPIOCNEWUNIT                        = 0xc004743e
+	PPPIOCSACTIVE                        = 0x40107446
+	PPPIOCSASYNCMAP                      = 0x40047457
+	PPPIOCSCOMPRESS                      = 0x4010744d
+	PPPIOCSDEBUG                         = 0x40047440
+	PPPIOCSFLAGS                         = 0x40047459
+	PPPIOCSMAXCID                        = 0x40047451
+	PPPIOCSMRRU                          = 0x4004743b
+	PPPIOCSMRU                           = 0x40047452
+	PPPIOCSNPMODE                        = 0x4008744b
+	PPPIOCSPASS                          = 0x40107447
+	PPPIOCSRASYNCMAP                     = 0x40047454
+	PPPIOCSXASYNCMAP                     = 0x4020744f
+	PPPIOCXFERUNIT                       = 0x744e
 	PRIO_PGRP                            = 0x1
 	PRIO_PROCESS                         = 0x0
 	PRIO_USER                            = 0x2
@@ -1757,6 +1787,7 @@ const (
 	SCM_TIMESTAMPNS                      = 0x23
 	SCM_TXTIME                           = 0x3d
 	SCM_WIFI_STATUS                      = 0x29
+	SC_LOG_FLUSH                         = 0x100000
 	SECCOMP_MODE_DISABLED                = 0x0
 	SECCOMP_MODE_FILTER                  = 0x2
 	SECCOMP_MODE_STRICT                  = 0x1
@@ -1812,6 +1843,9 @@ const (
 	SIOCGMIIPHY                          = 0x8947
 	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
+	SIOCGPPPCSTATS                       = 0x89f2
+	SIOCGPPPSTATS                        = 0x89f0
+	SIOCGPPPVER                          = 0x89f1
 	SIOCGRARP                            = 0x8961
 	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
index 28ef5242f..c146c1ad3 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
@@ -339,7 +339,7 @@ type Kevent_t struct {
 }
 
 type FdSet struct {
-	_ [32]uint32
+	Bits [32]uint32
 }
 
 const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
index e2d984a48..ac33a8dd4 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
@@ -337,7 +337,7 @@ type Kevent_t struct {
 }
 
 type FdSet struct {
-	_ [16]uint64
+	Bits [16]uint64
 }
 
 const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
index 9b415aba4..e27511a64 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
@@ -337,7 +337,7 @@ type Kevent_t struct {
 }
 
 type FdSet struct {
-	_ [32]uint32
+	Bits [32]uint32
 }
 
 const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
index 5f8f03492..f56e164b7 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
@@ -286,6 +286,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -421,6 +423,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
index aa52a439d..ac5f636a6 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
@@ -288,6 +288,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -425,6 +427,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
index 23c8438be..eb7562da7 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
@@ -289,6 +289,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]uint8
@@ -424,6 +426,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
index d7a993e25..3c4fb88d7 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
@@ -289,6 +289,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -426,6 +428,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
index b8c3d0a4d..647e40a77 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
@@ -287,6 +287,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -422,6 +424,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
index a6f76149a..e0159b01d 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
@@ -289,6 +289,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -426,6 +428,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
index 3dd194176..c1a024dfd 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
@@ -289,6 +289,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -426,6 +428,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
index 210de76cc..7e525eb7f 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
@@ -287,6 +287,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -422,6 +424,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
index b46d54e37..85ae2954d 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
@@ -290,6 +290,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]uint8
@@ -427,6 +429,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
index 6ee799cef..d0c930a13 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
@@ -290,6 +290,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]uint8
@@ -427,6 +429,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
index 60ae71e62..c1a20bcd3 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
@@ -289,6 +289,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]uint8
@@ -426,6 +428,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index dea88f7bb..3c26ea82b 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -288,6 +288,8 @@ type RawSockaddrXDP struct {
 	Shared_umem_fd uint32
 }
 
+type RawSockaddrPPPoX [0x1e]byte
+
 type RawSockaddr struct {
 	Family uint16
 	Data   [14]int8
@@ -425,6 +427,7 @@ const (
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofSockaddrXDP       = 0x10
+	SizeofSockaddrPPPoX     = 0x1e
 	SizeofLinger            = 0x8
 	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
index 1fdc5fd21..2dae0c17a 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
@@ -402,6 +402,13 @@ type Winsize struct {
 	Ypixel uint16
 }
 
+type Ptmget struct {
+	Cfd int32
+	Sfd int32
+	Cn  [1024]byte
+	Sn  [1024]byte
+}
+
 const (
 	AT_FDCWD            = -0x64
 	AT_SYMLINK_NOFOLLOW = 0x200
diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
index 711f78067..1f0e76c0c 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
@@ -409,6 +409,13 @@ type Winsize struct {
 	Ypixel uint16
 }
 
+type Ptmget struct {
+	Cfd int32
+	Sfd int32
+	Cn  [1024]byte
+	Sn  [1024]byte
+}
+
 const (
 	AT_FDCWD            = -0x64
 	AT_SYMLINK_NOFOLLOW = 0x200
diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
index fa1a16bae..53f2159c7 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
@@ -407,6 +407,13 @@ type Winsize struct {
 	Ypixel uint16
 }
 
+type Ptmget struct {
+	Cfd int32
+	Sfd int32
+	Cn  [1024]byte
+	Sn  [1024]byte
+}
+
 const (
 	AT_FDCWD            = -0x64
 	AT_SYMLINK_NOFOLLOW = 0x200
diff --git a/vendor/gopkg.in/go-playground/validator.v8/.gitignore b/vendor/gopkg.in/go-playground/validator.v8/.gitignore
new file mode 100644
index 000000000..792ca00d2
--- /dev/null
+++ b/vendor/gopkg.in/go-playground/validator.v8/.gitignore
@@ -0,0 +1,29 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+*.test
+*.out
+*.txt
+cover.html
+README.html
\ No newline at end of file
diff --git a/vendor/gopkg.in/go-playground/validator.v8/README.md b/vendor/gopkg.in/go-playground/validator.v8/README.md
new file mode 100644
index 000000000..758325928
--- /dev/null
+++ b/vendor/gopkg.in/go-playground/validator.v8/README.md
@@ -0,0 +1,367 @@
+Package validator
+================
+<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v8/logo.png">
+[![Join the chat at https://gitter.im/bluesuncorp/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+![Project status](https://img.shields.io/badge/version-8.18.1-green.svg)
+[![Build Status](https://semaphoreci.com/api/v1/projects/ec20115f-ef1b-4c7d-9393-cc76aba74eb4/530054/badge.svg)](https://semaphoreci.com/joeybloggs/validator)
+[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v8&service=github)](https://coveralls.io/github/go-playground/validator?branch=v8)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
+[![GoDoc](https://godoc.org/gopkg.in/go-playground/validator.v8?status.svg)](https://godoc.org/gopkg.in/go-playground/validator.v8)
+![License](https://img.shields.io/dub/l/vibe-d.svg)
+
+Package validator implements value validations for structs and individual fields based on tags.
+
+It has the following **unique** features:
+
+-   Cross Field and Cross Struct validations by using validation tags or custom validators.  
+-   Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.  
+-   Handles type interface by determining it's underlying type prior to validation.
+-   Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29)
+-   Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
+-   Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
+
+Installation
+------------
+
+Use go get.
+
+	go get gopkg.in/go-playground/validator.v8
+
+or to update
+
+	go get -u gopkg.in/go-playground/validator.v8
+
+Then import the validator package into your own code.
+
+	import "gopkg.in/go-playground/validator.v8"
+
+Error Return Value
+-------
+
+Validation functions return type error
+
+They return type error to avoid the issue discussed in the following, where err is always != nil:
+
+* http://stackoverflow.com/a/29138676/3158232
+* https://github.com/go-playground/validator/issues/134
+
+validator only returns nil or ValidationErrors as type error; so in you code all you need to do
+is check if the error returned is not nil, and if it's not type cast it to type ValidationErrors
+like so:
+
+```go
+err := validate.Struct(mystruct)
+validationErrors := err.(validator.ValidationErrors)
+ ```
+
+Usage and documentation
+------
+
+Please see http://godoc.org/gopkg.in/go-playground/validator.v8 for detailed usage docs.
+
+##### Examples:
+
+Struct & Field validation
+```go
+package main
+
+import (
+	"fmt"
+
+	"gopkg.in/go-playground/validator.v8"
+)
+
+// User contains user information
+type User struct {
+	FirstName      string     `validate:"required"`
+	LastName       string     `validate:"required"`
+	Age            uint8      `validate:"gte=0,lte=130"`
+	Email          string     `validate:"required,email"`
+	FavouriteColor string     `validate:"hexcolor|rgb|rgba"`
+	Addresses      []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
+}
+
+// Address houses a users address information
+type Address struct {
+	Street string `validate:"required"`
+	City   string `validate:"required"`
+	Planet string `validate:"required"`
+	Phone  string `validate:"required"`
+}
+
+var validate *validator.Validate
+
+func main() {
+
+	config := &validator.Config{TagName: "validate"}
+
+	validate = validator.New(config)
+
+	validateStruct()
+	validateField()
+}
+
+func validateStruct() {
+
+	address := &Address{
+		Street: "Eavesdown Docks",
+		Planet: "Persphone",
+		Phone:  "none",
+	}
+
+	user := &User{
+		FirstName:      "Badger",
+		LastName:       "Smith",
+		Age:            135,
+		Email:          "Badger.Smith@gmail.com",
+		FavouriteColor: "#000",
+		Addresses:      []*Address{address},
+	}
+
+	// returns nil or ValidationErrors ( map[string]*FieldError )
+	errs := validate.Struct(user)
+
+	if errs != nil {
+
+		fmt.Println(errs) // output: Key: "User.Age" Error:Field validation for "Age" failed on the "lte" tag
+		//	                         Key: "User.Addresses[0].City" Error:Field validation for "City" failed on the "required" tag
+		err := errs.(validator.ValidationErrors)["User.Addresses[0].City"]
+		fmt.Println(err.Field) // output: City
+		fmt.Println(err.Tag)   // output: required
+		fmt.Println(err.Kind)  // output: string
+		fmt.Println(err.Type)  // output: string
+		fmt.Println(err.Param) // output:
+		fmt.Println(err.Value) // output:
+
+		// from here you can create your own error messages in whatever language you wish
+		return
+	}
+
+	// save user to database
+}
+
+func validateField() {
+	myEmail := "joeybloggs.gmail.com"
+
+	errs := validate.Field(myEmail, "required,email")
+
+	if errs != nil {
+		fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag
+		return
+	}
+
+	// email ok, move on
+}
+```
+
+Custom Field Type
+```go
+package main
+
+import (
+	"database/sql"
+	"database/sql/driver"
+	"fmt"
+	"reflect"
+
+	"gopkg.in/go-playground/validator.v8"
+)
+
+// DbBackedUser User struct
+type DbBackedUser struct {
+	Name sql.NullString `validate:"required"`
+	Age  sql.NullInt64  `validate:"required"`
+}
+
+func main() {
+
+	config := &validator.Config{TagName: "validate"}
+
+	validate := validator.New(config)
+
+	// register all sql.Null* types to use the ValidateValuer CustomTypeFunc
+	validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
+
+	x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}}
+	errs := validate.Struct(x)
+
+	if len(errs.(validator.ValidationErrors)) > 0 {
+		fmt.Printf("Errs:\n%+v\n", errs)
+	}
+}
+
+// ValidateValuer implements validator.CustomTypeFunc
+func ValidateValuer(field reflect.Value) interface{} {
+	if valuer, ok := field.Interface().(driver.Valuer); ok {
+		val, err := valuer.Value()
+		if err == nil {
+			return val
+		}
+		// handle the error how you want
+	}
+	return nil
+}
+```
+
+Struct Level Validation
+```go
+package main
+
+import (
+	"fmt"
+	"reflect"
+
+	"gopkg.in/go-playground/validator.v8"
+)
+
+// User contains user information
+type User struct {
+	FirstName      string     `json:"fname"`
+	LastName       string     `json:"lname"`
+	Age            uint8      `validate:"gte=0,lte=130"`
+	Email          string     `validate:"required,email"`
+	FavouriteColor string     `validate:"hexcolor|rgb|rgba"`
+	Addresses      []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
+}
+
+// Address houses a users address information
+type Address struct {
+	Street string `validate:"required"`
+	City   string `validate:"required"`
+	Planet string `validate:"required"`
+	Phone  string `validate:"required"`
+}
+
+var validate *validator.Validate
+
+func main() {
+
+	config := &validator.Config{TagName: "validate"}
+
+	validate = validator.New(config)
+	validate.RegisterStructValidation(UserStructLevelValidation, User{})
+
+	validateStruct()
+}
+
+// UserStructLevelValidation contains custom struct level validations that don't always
+// make sense at the field validation level. For Example this function validates that either
+// FirstName or LastName exist; could have done that with a custom field validation but then
+// would have had to add it to both fields duplicating the logic + overhead, this way it's
+// only validated once.
+//
+// NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way
+// hooks right into validator and you can combine with validation tags and still have a
+// common error output format.
+func UserStructLevelValidation(v *validator.Validate, structLevel *validator.StructLevel) {
+
+	user := structLevel.CurrentStruct.Interface().(User)
+
+	if len(user.FirstName) == 0 && len(user.LastName) == 0 {
+		structLevel.ReportError(reflect.ValueOf(user.FirstName), "FirstName", "fname", "fnameorlname")
+		structLevel.ReportError(reflect.ValueOf(user.LastName), "LastName", "lname", "fnameorlname")
+	}
+
+	// plus can to more, even with different tag than "fnameorlname"
+}
+
+func validateStruct() {
+
+	address := &Address{
+		Street: "Eavesdown Docks",
+		Planet: "Persphone",
+		Phone:  "none",
+		City:   "Unknown",
+	}
+
+	user := &User{
+		FirstName:      "",
+		LastName:       "",
+		Age:            45,
+		Email:          "Badger.Smith@gmail.com",
+		FavouriteColor: "#000",
+		Addresses:      []*Address{address},
+	}
+
+	// returns nil or ValidationErrors ( map[string]*FieldError )
+	errs := validate.Struct(user)
+
+	if errs != nil {
+
+		fmt.Println(errs) // output: Key: 'User.LastName' Error:Field validation for 'LastName' failed on the 'fnameorlname' tag
+		//	                         Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'fnameorlname' tag
+		err := errs.(validator.ValidationErrors)["User.FirstName"]
+		fmt.Println(err.Field) // output: FirstName
+		fmt.Println(err.Tag)   // output: fnameorlname
+		fmt.Println(err.Kind)  // output: string
+		fmt.Println(err.Type)  // output: string
+		fmt.Println(err.Param) // output:
+		fmt.Println(err.Value) // output:
+
+		// from here you can create your own error messages in whatever language you wish
+		return
+	}
+
+	// save user to database
+}
+```
+
+Benchmarks
+------
+###### Run on MacBook Pro (Retina, 15-inch, Late 2013) 2.6 GHz Intel Core i7 16 GB 1600 MHz DDR3 using Go version go1.5.3 darwin/amd64
+```go
+PASS
+BenchmarkFieldSuccess-8                            	20000000	       118 ns/op	       0 B/op	       0 allocs/op
+BenchmarkFieldFailure-8                            	 2000000	       758 ns/op	     432 B/op	       4 allocs/op
+BenchmarkFieldDiveSuccess-8                        	  500000	      2471 ns/op	     464 B/op	      28 allocs/op
+BenchmarkFieldDiveFailure-8                        	  500000	      3172 ns/op	     896 B/op	      32 allocs/op
+BenchmarkFieldCustomTypeSuccess-8                  	 5000000	       300 ns/op	      32 B/op	       2 allocs/op
+BenchmarkFieldCustomTypeFailure-8                  	 2000000	       775 ns/op	     432 B/op	       4 allocs/op
+BenchmarkFieldOrTagSuccess-8                       	 1000000	      1122 ns/op	       4 B/op	       1 allocs/op
+BenchmarkFieldOrTagFailure-8                       	 1000000	      1167 ns/op	     448 B/op	       6 allocs/op
+BenchmarkStructLevelValidationSuccess-8            	 3000000	       548 ns/op	     160 B/op	       5 allocs/op
+BenchmarkStructLevelValidationFailure-8            	 3000000	       558 ns/op	     160 B/op	       5 allocs/op
+BenchmarkStructSimpleCustomTypeSuccess-8           	 2000000	       623 ns/op	      36 B/op	       3 allocs/op
+BenchmarkStructSimpleCustomTypeFailure-8           	 1000000	      1381 ns/op	     640 B/op	       9 allocs/op
+BenchmarkStructPartialSuccess-8                    	 1000000	      1036 ns/op	     272 B/op	       9 allocs/op
+BenchmarkStructPartialFailure-8                    	 1000000	      1734 ns/op	     730 B/op	      14 allocs/op
+BenchmarkStructExceptSuccess-8                     	 2000000	       888 ns/op	     250 B/op	       7 allocs/op
+BenchmarkStructExceptFailure-8                     	 1000000	      1036 ns/op	     272 B/op	       9 allocs/op
+BenchmarkStructSimpleCrossFieldSuccess-8           	 2000000	       773 ns/op	      80 B/op	       4 allocs/op
+BenchmarkStructSimpleCrossFieldFailure-8           	 1000000	      1487 ns/op	     536 B/op	       9 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldSuccess-8	 1000000	      1261 ns/op	     112 B/op	       7 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldFailure-8	 1000000	      2055 ns/op	     576 B/op	      12 allocs/op
+BenchmarkStructSimpleSuccess-8                     	 3000000	       519 ns/op	       4 B/op	       1 allocs/op
+BenchmarkStructSimpleFailure-8                     	 1000000	      1429 ns/op	     640 B/op	       9 allocs/op
+BenchmarkStructSimpleSuccessParallel-8             	10000000	       146 ns/op	       4 B/op	       1 allocs/op
+BenchmarkStructSimpleFailureParallel-8             	 2000000	       551 ns/op	     640 B/op	       9 allocs/op
+BenchmarkStructComplexSuccess-8                    	  500000	      3269 ns/op	     244 B/op	      15 allocs/op
+BenchmarkStructComplexFailure-8                    	  200000	      8436 ns/op	    3609 B/op	      60 allocs/op
+BenchmarkStructComplexSuccessParallel-8            	 1000000	      1024 ns/op	     244 B/op	      15 allocs/op
+BenchmarkStructComplexFailureParallel-8            	  500000	      3536 ns/op	    3609 B/op	      60 allocs/op
+```
+
+Complimentary Software
+----------------------
+
+Here is a list of software that compliments using this library either pre or post validation.
+
+* [Gorilla Schema](https://github.com/gorilla/schema) - Package gorilla/schema fills a struct with form values.
+* [Conform](https://github.com/leebenson/conform) - Trims, sanitizes & scrubs data based on struct tags.
+
+How to Contribute
+------
+
+There will always be a development branch for each version i.e. `v1-development`. In order to contribute, 
+please make your pull requests against those branches.
+
+If the changes being proposed or requested are breaking changes, please create an issue, for discussion
+or create a pull request against the highest development branch for example this package has a
+v1 and v1-development branch however, there will also be a v2-development branch even though v2 doesn't exist yet.
+
+I strongly encourage everyone whom creates a custom validation function to contribute them and
+help make this package even better.
+
+License
+------
+Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/gopkg.in/go-playground/validator.v8/logo.png b/vendor/gopkg.in/go-playground/validator.v8/logo.png
new file mode 100644
index 000000000..355000f52
Binary files /dev/null and b/vendor/gopkg.in/go-playground/validator.v8/logo.png differ
diff --git a/vendor/gopkg.in/inconshreveable/go-update.v0/README.md b/vendor/gopkg.in/inconshreveable/go-update.v0/README.md
new file mode 100644
index 000000000..f070062c2
--- /dev/null
+++ b/vendor/gopkg.in/inconshreveable/go-update.v0/README.md
@@ -0,0 +1,37 @@
+# go-update: Automatically update Go programs from the internet
+
+go-update allows a program to update itself by replacing its executable file
+with a new version. It provides the flexibility to implement different updating user experiences
+like auto-updating, or manual user-initiated updates. It also boasts
+advanced features like binary patching and code signing verification.
+
+Updating your program to a new version is as easy as:
+
+	err, errRecover := update.New().FromUrl("http://release.example.com/2.0/myprogram")
+	if err != nil {
+		fmt.Printf("Update failed: %v\n", err)
+	}
+
+## Documentation and API Reference
+
+Comprehensive API documentation and code examples are available in the code documentation available on godoc.org:
+
+[![GoDoc](https://godoc.org/github.com/inconshreveable/go-update?status.svg)](https://godoc.org/github.com/inconshreveable/go-update)
+
+## Features
+
+- Cross platform support (Windows too!)
+- Binary patch application
+- Checksum verification
+- Code signing verification
+- Support for updating arbitrary files
+
+## [equinox.io](https://equinox.io)
+go-update provides the primitives for building self-updating applications, but there a number of other challenges
+involved in a complete updating solution such as hosting, code signing, update channels, gradual rollout,
+dynamically computing binary patches, tracking update metrics like versions and failures, plus more.
+
+I provide this service, a complete solution, free for open source projects, at [equinox.io](https://equinox.io).
+
+## License
+Apache
diff --git a/vendor/gopkg.in/yaml.v2/.travis.yml b/vendor/gopkg.in/yaml.v2/.travis.yml
new file mode 100644
index 000000000..004172a2e
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+
+go:
+    - 1.4
+    - 1.5
+    - 1.6
+    - tip
+
+go_import_path: gopkg.in/yaml.v2
diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE
index 8dada3eda..866d74a7a 100644
--- a/vendor/gopkg.in/yaml.v2/LICENSE
+++ b/vendor/gopkg.in/yaml.v2/LICENSE
@@ -1,201 +1,13 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
+Copyright 2011-2016 Canonical Ltd.
 
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
 
-   1. Definitions.
+    http://www.apache.org/licenses/LICENSE-2.0
 
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/gopkg.in/yaml.v2/NOTICE b/vendor/gopkg.in/yaml.v2/NOTICE
deleted file mode 100644
index 866d74a7a..000000000
--- a/vendor/gopkg.in/yaml.v2/NOTICE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2011-2016 Canonical Ltd.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md
new file mode 100644
index 000000000..1884de6a7
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/README.md
@@ -0,0 +1,131 @@
+# YAML support for the Go language
+
+Introduction
+------------
+
+The yaml package enables Go programs to comfortably encode and decode YAML
+values. It was developed within [Canonical](https://www.canonical.com) as
+part of the [juju](https://juju.ubuntu.com) project, and is based on a
+pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
+C library to parse and generate YAML data quickly and reliably.
+
+Compatibility
+-------------
+
+The yaml package supports most of YAML 1.1 and 1.2, including support for
+anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
+implemented, and base-60 floats from YAML 1.1 are purposefully not
+supported since they're a poor design and are gone in YAML 1.2.
+
+Installation and usage
+----------------------
+
+The import path for the package is *gopkg.in/yaml.v2*.
+
+To install it, run:
+
+    go get gopkg.in/yaml.v2
+
+API documentation
+-----------------
+
+If opened in a browser, the import path itself leads to the API documentation:
+
+  * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
+
+API stability
+-------------
+
+The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
+
+
+License
+-------
+
+The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
+
+
+Example
+-------
+
+```Go
+package main
+
+import (
+        "fmt"
+        "log"
+
+        "gopkg.in/yaml.v2"
+)
+
+var data = `
+a: Easy!
+b:
+  c: 2
+  d: [3, 4]
+`
+
+type T struct {
+        A string
+        B struct {
+                RenamedC int   `yaml:"c"`
+                D        []int `yaml:",flow"`
+        }
+}
+
+func main() {
+        t := T{}
+    
+        err := yaml.Unmarshal([]byte(data), &t)
+        if err != nil {
+                log.Fatalf("error: %v", err)
+        }
+        fmt.Printf("--- t:\n%v\n\n", t)
+    
+        d, err := yaml.Marshal(&t)
+        if err != nil {
+                log.Fatalf("error: %v", err)
+        }
+        fmt.Printf("--- t dump:\n%s\n\n", string(d))
+    
+        m := make(map[interface{}]interface{})
+    
+        err = yaml.Unmarshal([]byte(data), &m)
+        if err != nil {
+                log.Fatalf("error: %v", err)
+        }
+        fmt.Printf("--- m:\n%v\n\n", m)
+    
+        d, err = yaml.Marshal(&m)
+        if err != nil {
+                log.Fatalf("error: %v", err)
+        }
+        fmt.Printf("--- m dump:\n%s\n\n", string(d))
+}
+```
+
+This example will generate the following output:
+
+```
+--- t:
+{Easy! {2 [3 4]}}
+
+--- t dump:
+a: Easy!
+b:
+  c: 2
+  d: [3, 4]
+
+
+--- m:
+map[a:Easy! b:map[c:2 d:[3 4]]]
+
+--- m dump:
+a: Easy!
+b:
+  c: 2
+  d:
+  - 3
+  - 4
+```
+
diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go
index 1f7e87e67..95ec014e8 100644
--- a/vendor/gopkg.in/yaml.v2/apic.go
+++ b/vendor/gopkg.in/yaml.v2/apic.go
@@ -2,6 +2,7 @@ package yaml
 
 import (
 	"io"
+	"os"
 )
 
 func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
@@ -47,9 +48,9 @@ func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err
 	return n, nil
 }
 
-// Reader read handler.
-func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
-	return parser.input_reader.Read(buffer)
+// File read handler.
+func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
+	return parser.input_file.Read(buffer)
 }
 
 // Set a string input.
@@ -63,12 +64,12 @@ func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
 }
 
 // Set a file input.
-func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
+func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
 	if parser.read_handler != nil {
 		panic("must set the input source only once")
 	}
-	parser.read_handler = yaml_reader_read_handler
-	parser.input_reader = r
+	parser.read_handler = yaml_file_read_handler
+	parser.input_file = file
 }
 
 // Set the source encoding.
@@ -80,13 +81,14 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
 }
 
 // Create a new emitter object.
-func yaml_emitter_initialize(emitter *yaml_emitter_t) {
+func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
 	*emitter = yaml_emitter_t{
 		buffer:     make([]byte, output_buffer_size),
 		raw_buffer: make([]byte, 0, output_raw_buffer_size),
 		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
 		events:     make([]yaml_event_t, 0, initial_queue_size),
 	}
+	return true
 }
 
 // Destroy an emitter object.
@@ -100,10 +102,9 @@ func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
 	return nil
 }
 
-// yaml_writer_write_handler uses emitter.output_writer to write the
-// emitted text.
-func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
-	_, err := emitter.output_writer.Write(buffer)
+// File write handler.
+func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+	_, err := emitter.output_file.Write(buffer)
 	return err
 }
 
@@ -117,12 +118,12 @@ func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]by
 }
 
 // Set a file output.
-func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
+func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
 	if emitter.write_handler != nil {
 		panic("must set the output target only once")
 	}
-	emitter.write_handler = yaml_writer_write_handler
-	emitter.output_writer = w
+	emitter.write_handler = yaml_file_write_handler
+	emitter.output_file = file
 }
 
 // Set the output encoding.
@@ -251,41 +252,41 @@ func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
 //
 
 // Create STREAM-START.
-func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
+func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
 	*event = yaml_event_t{
 		typ:      yaml_STREAM_START_EVENT,
 		encoding: encoding,
 	}
+	return true
 }
 
 // Create STREAM-END.
-func yaml_stream_end_event_initialize(event *yaml_event_t) {
+func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
 	*event = yaml_event_t{
 		typ: yaml_STREAM_END_EVENT,
 	}
+	return true
 }
 
 // Create DOCUMENT-START.
-func yaml_document_start_event_initialize(
-	event *yaml_event_t,
-	version_directive *yaml_version_directive_t,
-	tag_directives []yaml_tag_directive_t,
-	implicit bool,
-) {
+func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
+	tag_directives []yaml_tag_directive_t, implicit bool) bool {
 	*event = yaml_event_t{
 		typ:               yaml_DOCUMENT_START_EVENT,
 		version_directive: version_directive,
 		tag_directives:    tag_directives,
 		implicit:          implicit,
 	}
+	return true
 }
 
 // Create DOCUMENT-END.
-func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
+func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
 	*event = yaml_event_t{
 		typ:      yaml_DOCUMENT_END_EVENT,
 		implicit: implicit,
 	}
+	return true
 }
 
 ///*
@@ -347,7 +348,7 @@ func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
 }
 
 // Create MAPPING-START.
-func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
+func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
 	*event = yaml_event_t{
 		typ:      yaml_MAPPING_START_EVENT,
 		anchor:   anchor,
@@ -355,13 +356,15 @@ func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte
 		implicit: implicit,
 		style:    yaml_style_t(style),
 	}
+	return true
 }
 
 // Create MAPPING-END.
-func yaml_mapping_end_event_initialize(event *yaml_event_t) {
+func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
 	*event = yaml_event_t{
 		typ: yaml_MAPPING_END_EVENT,
 	}
+	return true
 }
 
 // Destroy an event object.
@@ -468,7 +471,7 @@ func yaml_event_delete(event *yaml_event_t) {
 //    } context
 //    tag_directive *yaml_tag_directive_t
 //
-//    context.error = YAML_NO_ERROR // Eliminate a compiler warning.
+//    context.error = YAML_NO_ERROR // Eliminate a compliler warning.
 //
 //    assert(document) // Non-NULL document object is expected.
 //
diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go
index e4e56e28e..b13ab9f07 100644
--- a/vendor/gopkg.in/yaml.v2/decode.go
+++ b/vendor/gopkg.in/yaml.v2/decode.go
@@ -4,7 +4,6 @@ import (
 	"encoding"
 	"encoding/base64"
 	"fmt"
-	"io"
 	"math"
 	"reflect"
 	"strconv"
@@ -23,22 +22,19 @@ type node struct {
 	kind         int
 	line, column int
 	tag          string
-	// For an alias node, alias holds the resolved alias.
-	alias    *node
-	value    string
-	implicit bool
-	children []*node
-	anchors  map[string]*node
+	value        string
+	implicit     bool
+	children     []*node
+	anchors      map[string]*node
 }
 
 // ----------------------------------------------------------------------------
 // Parser, produces a node tree out of a libyaml event stream.
 
 type parser struct {
-	parser   yaml_parser_t
-	event    yaml_event_t
-	doc      *node
-	doneInit bool
+	parser yaml_parser_t
+	event  yaml_event_t
+	doc    *node
 }
 
 func newParser(b []byte) *parser {
@@ -46,30 +42,21 @@ func newParser(b []byte) *parser {
 	if !yaml_parser_initialize(&p.parser) {
 		panic("failed to initialize YAML emitter")
 	}
+
 	if len(b) == 0 {
 		b = []byte{'\n'}
 	}
+
 	yaml_parser_set_input_string(&p.parser, b)
-	return &p
-}
 
-func newParserFromReader(r io.Reader) *parser {
-	p := parser{}
-	if !yaml_parser_initialize(&p.parser) {
-		panic("failed to initialize YAML emitter")
+	p.skip()
+	if p.event.typ != yaml_STREAM_START_EVENT {
+		panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
 	}
-	yaml_parser_set_input_reader(&p.parser, r)
+	p.skip()
 	return &p
 }
 
-func (p *parser) init() {
-	if p.doneInit {
-		return
-	}
-	p.expect(yaml_STREAM_START_EVENT)
-	p.doneInit = true
-}
-
 func (p *parser) destroy() {
 	if p.event.typ != yaml_NO_EVENT {
 		yaml_event_delete(&p.event)
@@ -77,35 +64,16 @@ func (p *parser) destroy() {
 	yaml_parser_delete(&p.parser)
 }
 
-// expect consumes an event from the event stream and
-// checks that it's of the expected type.
-func (p *parser) expect(e yaml_event_type_t) {
-	if p.event.typ == yaml_NO_EVENT {
-		if !yaml_parser_parse(&p.parser, &p.event) {
-			p.fail()
-		}
-	}
-	if p.event.typ == yaml_STREAM_END_EVENT {
-		failf("attempted to go past the end of stream; corrupted value?")
-	}
-	if p.event.typ != e {
-		p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
-		p.fail()
-	}
-	yaml_event_delete(&p.event)
-	p.event.typ = yaml_NO_EVENT
-}
-
-// peek peeks at the next event in the event stream,
-// puts the results into p.event and returns the event type.
-func (p *parser) peek() yaml_event_type_t {
+func (p *parser) skip() {
 	if p.event.typ != yaml_NO_EVENT {
-		return p.event.typ
+		if p.event.typ == yaml_STREAM_END_EVENT {
+			failf("attempted to go past the end of stream; corrupted value?")
+		}
+		yaml_event_delete(&p.event)
 	}
 	if !yaml_parser_parse(&p.parser, &p.event) {
 		p.fail()
 	}
-	return p.event.typ
 }
 
 func (p *parser) fail() {
@@ -113,10 +81,6 @@ func (p *parser) fail() {
 	var line int
 	if p.parser.problem_mark.line != 0 {
 		line = p.parser.problem_mark.line
-		// Scanner errors don't iterate line before returning error
-		if p.parser.error == yaml_SCANNER_ERROR {
-			line++
-		}
 	} else if p.parser.context_mark.line != 0 {
 		line = p.parser.context_mark.line
 	}
@@ -139,8 +103,7 @@ func (p *parser) anchor(n *node, anchor []byte) {
 }
 
 func (p *parser) parse() *node {
-	p.init()
-	switch p.peek() {
+	switch p.event.typ {
 	case yaml_SCALAR_EVENT:
 		return p.scalar()
 	case yaml_ALIAS_EVENT:
@@ -155,8 +118,9 @@ func (p *parser) parse() *node {
 		// Happens when attempting to decode an empty buffer.
 		return nil
 	default:
-		panic("attempted to parse unknown event: " + p.event.typ.String())
+		panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
 	}
+	panic("unreachable")
 }
 
 func (p *parser) node(kind int) *node {
@@ -171,20 +135,19 @@ func (p *parser) document() *node {
 	n := p.node(documentNode)
 	n.anchors = make(map[string]*node)
 	p.doc = n
-	p.expect(yaml_DOCUMENT_START_EVENT)
+	p.skip()
 	n.children = append(n.children, p.parse())
-	p.expect(yaml_DOCUMENT_END_EVENT)
+	if p.event.typ != yaml_DOCUMENT_END_EVENT {
+		panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
+	}
+	p.skip()
 	return n
 }
 
 func (p *parser) alias() *node {
 	n := p.node(aliasNode)
 	n.value = string(p.event.anchor)
-	n.alias = p.doc.anchors[n.value]
-	if n.alias == nil {
-		failf("unknown anchor '%s' referenced", n.value)
-	}
-	p.expect(yaml_ALIAS_EVENT)
+	p.skip()
 	return n
 }
 
@@ -194,29 +157,29 @@ func (p *parser) scalar() *node {
 	n.tag = string(p.event.tag)
 	n.implicit = p.event.implicit
 	p.anchor(n, p.event.anchor)
-	p.expect(yaml_SCALAR_EVENT)
+	p.skip()
 	return n
 }
 
 func (p *parser) sequence() *node {
 	n := p.node(sequenceNode)
 	p.anchor(n, p.event.anchor)
-	p.expect(yaml_SEQUENCE_START_EVENT)
-	for p.peek() != yaml_SEQUENCE_END_EVENT {
+	p.skip()
+	for p.event.typ != yaml_SEQUENCE_END_EVENT {
 		n.children = append(n.children, p.parse())
 	}
-	p.expect(yaml_SEQUENCE_END_EVENT)
+	p.skip()
 	return n
 }
 
 func (p *parser) mapping() *node {
 	n := p.node(mappingNode)
 	p.anchor(n, p.event.anchor)
-	p.expect(yaml_MAPPING_START_EVENT)
-	for p.peek() != yaml_MAPPING_END_EVENT {
+	p.skip()
+	for p.event.typ != yaml_MAPPING_END_EVENT {
 		n.children = append(n.children, p.parse(), p.parse())
 	}
-	p.expect(yaml_MAPPING_END_EVENT)
+	p.skip()
 	return n
 }
 
@@ -225,10 +188,9 @@ func (p *parser) mapping() *node {
 
 type decoder struct {
 	doc     *node
-	aliases map[*node]bool
+	aliases map[string]bool
 	mapType reflect.Type
 	terrors []string
-	strict  bool
 }
 
 var (
@@ -236,13 +198,11 @@ var (
 	durationType   = reflect.TypeOf(time.Duration(0))
 	defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
 	ifaceType      = defaultMapType.Elem()
-	timeType       = reflect.TypeOf(time.Time{})
-	ptrTimeType    = reflect.TypeOf(&time.Time{})
 )
 
-func newDecoder(strict bool) *decoder {
-	d := &decoder{mapType: defaultMapType, strict: strict}
-	d.aliases = make(map[*node]bool)
+func newDecoder() *decoder {
+	d := &decoder{mapType: defaultMapType}
+	d.aliases = make(map[string]bool)
 	return d
 }
 
@@ -291,7 +251,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
 //
 // If n holds a null value, prepare returns before doing anything.
 func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
-	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
+	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "" && n.implicit) {
 		return out, false, false
 	}
 	again := true
@@ -348,13 +308,16 @@ func (d *decoder) document(n *node, out reflect.Value) (good bool) {
 }
 
 func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
-	if d.aliases[n] {
-		// TODO this could actually be allowed in some circumstances.
+	an, ok := d.doc.anchors[n.value]
+	if !ok {
+		failf("unknown anchor '%s' referenced", n.value)
+	}
+	if d.aliases[n.value] {
 		failf("anchor '%s' value contains itself", n.value)
 	}
-	d.aliases[n] = true
-	good = d.unmarshal(n.alias, out)
-	delete(d.aliases, n)
+	d.aliases[n.value] = true
+	good = d.unmarshal(an, out)
+	delete(d.aliases, n.value)
 	return good
 }
 
@@ -366,7 +329,7 @@ func resetMap(out reflect.Value) {
 	}
 }
 
-func (d *decoder) scalar(n *node, out reflect.Value) bool {
+func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 	var tag string
 	var resolved interface{}
 	if n.tag == "" && !n.implicit {
@@ -390,26 +353,9 @@ func (d *decoder) scalar(n *node, out reflect.Value) bool {
 		}
 		return true
 	}
-	if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
-		// We've resolved to exactly the type we want, so use that.
-		out.Set(resolvedv)
-		return true
-	}
-	// Perhaps we can use the value as a TextUnmarshaler to
-	// set its value.
-	if out.CanAddr() {
-		u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
-		if ok {
-			var text []byte
-			if tag == yaml_BINARY_TAG {
-				text = []byte(resolved.(string))
-			} else {
-				// We let any value be unmarshaled into TextUnmarshaler.
-				// That might be more lax than we'd like, but the
-				// TextUnmarshaler itself should bowl out any dubious values.
-				text = []byte(n.value)
-			}
-			err := u.UnmarshalText(text)
+	if s, ok := resolved.(string); ok && out.CanAddr() {
+		if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
+			err := u.UnmarshalText([]byte(s))
 			if err != nil {
 				fail(err)
 			}
@@ -420,54 +366,46 @@ func (d *decoder) scalar(n *node, out reflect.Value) bool {
 	case reflect.String:
 		if tag == yaml_BINARY_TAG {
 			out.SetString(resolved.(string))
-			return true
-		}
-		if resolved != nil {
+			good = true
+		} else if resolved != nil {
 			out.SetString(n.value)
-			return true
+			good = true
 		}
 	case reflect.Interface:
 		if resolved == nil {
 			out.Set(reflect.Zero(out.Type()))
-		} else if tag == yaml_TIMESTAMP_TAG {
-			// It looks like a timestamp but for backward compatibility
-			// reasons we set it as a string, so that code that unmarshals
-			// timestamp-like values into interface{} will continue to
-			// see a string and not a time.Time.
-			// TODO(v3) Drop this.
-			out.Set(reflect.ValueOf(n.value))
 		} else {
 			out.Set(reflect.ValueOf(resolved))
 		}
-		return true
+		good = true
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		switch resolved := resolved.(type) {
 		case int:
 			if !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
-				return true
+				good = true
 			}
 		case int64:
 			if !out.OverflowInt(resolved) {
 				out.SetInt(resolved)
-				return true
+				good = true
 			}
 		case uint64:
 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
-				return true
+				good = true
 			}
 		case float64:
 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
-				return true
+				good = true
 			}
 		case string:
 			if out.Type() == durationType {
 				d, err := time.ParseDuration(resolved)
 				if err == nil {
 					out.SetInt(int64(d))
-					return true
+					good = true
 				}
 			}
 		}
@@ -476,49 +414,44 @@ func (d *decoder) scalar(n *node, out reflect.Value) bool {
 		case int:
 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
-				return true
+				good = true
 			}
 		case int64:
 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
-				return true
+				good = true
 			}
 		case uint64:
 			if !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
-				return true
+				good = true
 			}
 		case float64:
 			if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
-				return true
+				good = true
 			}
 		}
 	case reflect.Bool:
 		switch resolved := resolved.(type) {
 		case bool:
 			out.SetBool(resolved)
-			return true
+			good = true
 		}
 	case reflect.Float32, reflect.Float64:
 		switch resolved := resolved.(type) {
 		case int:
 			out.SetFloat(float64(resolved))
-			return true
+			good = true
 		case int64:
 			out.SetFloat(float64(resolved))
-			return true
+			good = true
 		case uint64:
 			out.SetFloat(float64(resolved))
-			return true
+			good = true
 		case float64:
 			out.SetFloat(resolved)
-			return true
-		}
-	case reflect.Struct:
-		if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
-			out.Set(resolvedv)
-			return true
+			good = true
 		}
 	case reflect.Ptr:
 		if out.Type().Elem() == reflect.TypeOf(resolved) {
@@ -526,11 +459,13 @@ func (d *decoder) scalar(n *node, out reflect.Value) bool {
 			elem := reflect.New(out.Type().Elem())
 			elem.Elem().Set(reflect.ValueOf(resolved))
 			out.Set(elem)
-			return true
+			good = true
 		}
 	}
-	d.terror(n, tag, out)
-	return false
+	if !good {
+		d.terror(n, tag, out)
+	}
+	return good
 }
 
 func settableValueOf(i interface{}) reflect.Value {
@@ -547,10 +482,6 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 	switch out.Kind() {
 	case reflect.Slice:
 		out.Set(reflect.MakeSlice(out.Type(), l, l))
-	case reflect.Array:
-		if l != out.Len() {
-			failf("invalid array: want %d elements but got %d", out.Len(), l)
-		}
 	case reflect.Interface:
 		// No type hints. Will have to use a generic sequence.
 		iface = out
@@ -569,9 +500,7 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 			j++
 		}
 	}
-	if out.Kind() != reflect.Array {
-		out.Set(out.Slice(0, j))
-	}
+	out.Set(out.Slice(0, j))
 	if iface.IsValid() {
 		iface.Set(out)
 	}
@@ -632,7 +561,7 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 			}
 			e := reflect.New(et).Elem()
 			if d.unmarshal(n.children[i+1], e) {
-				d.setMapIndex(n.children[i+1], out, k, e)
+				out.SetMapIndex(k, e)
 			}
 		}
 	}
@@ -640,14 +569,6 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 	return true
 }
 
-func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
-	if d.strict && out.MapIndex(k) != zeroValue {
-		d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
-		return
-	}
-	out.SetMapIndex(k, v)
-}
-
 func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
 	outt := out.Type()
 	if outt.Elem() != mapItemType {
@@ -695,10 +616,6 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 		elemType = inlineMap.Type().Elem()
 	}
 
-	var doneFields []bool
-	if d.strict {
-		doneFields = make([]bool, len(sinfo.FieldsList))
-	}
 	for i := 0; i < l; i += 2 {
 		ni := n.children[i]
 		if isMerge(ni) {
@@ -709,13 +626,6 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 			continue
 		}
 		if info, ok := sinfo.FieldsMap[name.String()]; ok {
-			if d.strict {
-				if doneFields[info.Id] {
-					d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
-					continue
-				}
-				doneFields[info.Id] = true
-			}
 			var field reflect.Value
 			if info.Inline == nil {
 				field = out.Field(info.Num)
@@ -729,9 +639,7 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 			}
 			value := reflect.New(elemType).Elem()
 			d.unmarshal(n.children[i+1], value)
-			d.setMapIndex(n.children[i+1], inlineMap, name, value)
-		} else if d.strict {
-			d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
+			inlineMap.SetMapIndex(name, value)
 		}
 	}
 	return true
diff --git a/vendor/gopkg.in/yaml.v2/emitterc.go b/vendor/gopkg.in/yaml.v2/emitterc.go
index a1c2cc526..2befd553e 100644
--- a/vendor/gopkg.in/yaml.v2/emitterc.go
+++ b/vendor/gopkg.in/yaml.v2/emitterc.go
@@ -2,7 +2,6 @@ package yaml
 
 import (
 	"bytes"
-	"fmt"
 )
 
 // Flush the buffer if needed.
@@ -665,8 +664,9 @@ func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
 		return yaml_emitter_emit_mapping_start(emitter, event)
 	default:
 		return yaml_emitter_set_emitter_error(emitter,
-			fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
+			"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
 	}
+	return false
 }
 
 // Expect ALIAS.
@@ -843,7 +843,7 @@ func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event
 	return true
 }
 
-// Write an anchor.
+// Write an achor.
 func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
 	if emitter.anchor_data.anchor == nil {
 		return true
@@ -995,10 +995,10 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 		break_space    = false
 		space_break    = false
 
-		preceded_by_whitespace = false
-		followed_by_whitespace = false
-		previous_space         = false
-		previous_break         = false
+		preceeded_by_whitespace = false
+		followed_by_whitespace  = false
+		previous_space          = false
+		previous_break          = false
 	)
 
 	emitter.scalar_data.value = value
@@ -1017,7 +1017,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 		flow_indicators = true
 	}
 
-	preceded_by_whitespace = true
+	preceeded_by_whitespace = true
 	for i, w := 0, 0; i < len(value); i += w {
 		w = width(value[i])
 		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
@@ -1048,7 +1048,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 					block_indicators = true
 				}
 			case '#':
-				if preceded_by_whitespace {
+				if preceeded_by_whitespace {
 					flow_indicators = true
 					block_indicators = true
 				}
@@ -1089,7 +1089,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 		}
 
 		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
-		preceded_by_whitespace = is_blankz(value, i)
+		preceeded_by_whitespace = is_blankz(value, i)
 	}
 
 	emitter.scalar_data.multiline = line_breaks
diff --git a/vendor/gopkg.in/yaml.v2/encode.go b/vendor/gopkg.in/yaml.v2/encode.go
index a14435e82..84f849955 100644
--- a/vendor/gopkg.in/yaml.v2/encode.go
+++ b/vendor/gopkg.in/yaml.v2/encode.go
@@ -3,14 +3,12 @@ package yaml
 import (
 	"encoding"
 	"fmt"
-	"io"
 	"reflect"
 	"regexp"
 	"sort"
 	"strconv"
 	"strings"
 	"time"
-	"unicode/utf8"
 )
 
 type encoder struct {
@@ -18,39 +16,25 @@ type encoder struct {
 	event   yaml_event_t
 	out     []byte
 	flow    bool
-	// doneInit holds whether the initial stream_start_event has been
-	// emitted.
-	doneInit bool
 }
 
-func newEncoder() *encoder {
-	e := &encoder{}
-	yaml_emitter_initialize(&e.emitter)
+func newEncoder() (e *encoder) {
+	e = &encoder{}
+	e.must(yaml_emitter_initialize(&e.emitter))
 	yaml_emitter_set_output_string(&e.emitter, &e.out)
 	yaml_emitter_set_unicode(&e.emitter, true)
-	return e
-}
-
-func newEncoderWithWriter(w io.Writer) *encoder {
-	e := &encoder{}
-	yaml_emitter_initialize(&e.emitter)
-	yaml_emitter_set_output_writer(&e.emitter, w)
-	yaml_emitter_set_unicode(&e.emitter, true)
-	return e
-}
-
-func (e *encoder) init() {
-	if e.doneInit {
-		return
-	}
-	yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
+	e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
+	e.emit()
+	e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
 	e.emit()
-	e.doneInit = true
+	return e
 }
 
 func (e *encoder) finish() {
+	e.must(yaml_document_end_event_initialize(&e.event, true))
+	e.emit()
 	e.emitter.open_ended = false
-	yaml_stream_end_event_initialize(&e.event)
+	e.must(yaml_stream_end_event_initialize(&e.event))
 	e.emit()
 }
 
@@ -60,7 +44,9 @@ func (e *encoder) destroy() {
 
 func (e *encoder) emit() {
 	// This will internally delete the e.event value.
-	e.must(yaml_emitter_emit(&e.emitter, &e.event))
+	if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
+		e.must(false)
+	}
 }
 
 func (e *encoder) must(ok bool) {
@@ -73,28 +59,13 @@ func (e *encoder) must(ok bool) {
 	}
 }
 
-func (e *encoder) marshalDoc(tag string, in reflect.Value) {
-	e.init()
-	yaml_document_start_event_initialize(&e.event, nil, nil, true)
-	e.emit()
-	e.marshal(tag, in)
-	yaml_document_end_event_initialize(&e.event, true)
-	e.emit()
-}
-
 func (e *encoder) marshal(tag string, in reflect.Value) {
-	if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
+	if !in.IsValid() {
 		e.nilv()
 		return
 	}
 	iface := in.Interface()
-	switch m := iface.(type) {
-	case time.Time, *time.Time:
-		// Although time.Time implements TextMarshaler,
-		// we don't want to treat it as a string for YAML
-		// purposes because YAML has special support for
-		// timestamps.
-	case Marshaler:
+	if m, ok := iface.(Marshaler); ok {
 		v, err := m.MarshalYAML()
 		if err != nil {
 			fail(err)
@@ -104,34 +75,31 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
 			return
 		}
 		in = reflect.ValueOf(v)
-	case encoding.TextMarshaler:
+	} else if m, ok := iface.(encoding.TextMarshaler); ok {
 		text, err := m.MarshalText()
 		if err != nil {
 			fail(err)
 		}
 		in = reflect.ValueOf(string(text))
-	case nil:
-		e.nilv()
-		return
 	}
 	switch in.Kind() {
 	case reflect.Interface:
-		e.marshal(tag, in.Elem())
+		if in.IsNil() {
+			e.nilv()
+		} else {
+			e.marshal(tag, in.Elem())
+		}
 	case reflect.Map:
 		e.mapv(tag, in)
 	case reflect.Ptr:
-		if in.Type() == ptrTimeType {
-			e.timev(tag, in.Elem())
+		if in.IsNil() {
+			e.nilv()
 		} else {
 			e.marshal(tag, in.Elem())
 		}
 	case reflect.Struct:
-		if in.Type() == timeType {
-			e.timev(tag, in)
-		} else {
-			e.structv(tag, in)
-		}
-	case reflect.Slice, reflect.Array:
+		e.structv(tag, in)
+	case reflect.Slice:
 		if in.Type().Elem() == mapItemType {
 			e.itemsv(tag, in)
 		} else {
@@ -223,10 +191,10 @@ func (e *encoder) mappingv(tag string, f func()) {
 		e.flow = false
 		style = yaml_FLOW_MAPPING_STYLE
 	}
-	yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
+	e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
 	e.emit()
 	f()
-	yaml_mapping_end_event_initialize(&e.event)
+	e.must(yaml_mapping_end_event_initialize(&e.event))
 	e.emit()
 }
 
@@ -272,36 +240,23 @@ var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0
 func (e *encoder) stringv(tag string, in reflect.Value) {
 	var style yaml_scalar_style_t
 	s := in.String()
-	canUsePlain := true
-	switch {
-	case !utf8.ValidString(s):
-		if tag == yaml_BINARY_TAG {
+	rtag, rs := resolve("", s)
+	if rtag == yaml_BINARY_TAG {
+		if tag == "" || tag == yaml_STR_TAG {
+			tag = rtag
+			s = rs.(string)
+		} else if tag == yaml_BINARY_TAG {
 			failf("explicitly tagged !!binary data must be base64-encoded")
-		}
-		if tag != "" {
+		} else {
 			failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
 		}
-		// It can't be encoded directly as YAML so use a binary tag
-		// and encode it as base64.
-		tag = yaml_BINARY_TAG
-		s = encodeBase64(s)
-	case tag == "":
-		// Check to see if it would resolve to a specific
-		// tag when encoded unquoted. If it doesn't,
-		// there's no need to quote it.
-		rtag, _ := resolve("", s)
-		canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
 	}
-	// Note: it's possible for user code to emit invalid YAML
-	// if they explicitly specify a tag and a string containing
-	// text that's incompatible with that tag.
-	switch {
-	case strings.Contains(s, "\n"):
+	if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
+		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+	} else if strings.Contains(s, "\n") {
 		style = yaml_LITERAL_SCALAR_STYLE
-	case canUsePlain:
+	} else {
 		style = yaml_PLAIN_SCALAR_STYLE
-	default:
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 	}
 	e.emitScalar(s, "", tag, style)
 }
@@ -326,20 +281,9 @@ func (e *encoder) uintv(tag string, in reflect.Value) {
 	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
 }
 
-func (e *encoder) timev(tag string, in reflect.Value) {
-	t := in.Interface().(time.Time)
-	s := t.Format(time.RFC3339Nano)
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
 func (e *encoder) floatv(tag string, in reflect.Value) {
-	// Issue #352: When formatting, use the precision of the underlying value
-	precision := 64
-	if in.Kind() == reflect.Float32 {
-		precision = 32
-	}
-
-	s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
+	// FIXME: Handle 64 bits here.
+	s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
 	switch s {
 	case "+Inf":
 		s = ".inf"
diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go
index 81d05dfe5..0a7037ad1 100644
--- a/vendor/gopkg.in/yaml.v2/parserc.go
+++ b/vendor/gopkg.in/yaml.v2/parserc.go
@@ -166,6 +166,7 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool
 	default:
 		panic("invalid parser state")
 	}
+	return false
 }
 
 // Parse the production:
diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go
index 7c1f5fac3..f45079171 100644
--- a/vendor/gopkg.in/yaml.v2/readerc.go
+++ b/vendor/gopkg.in/yaml.v2/readerc.go
@@ -93,18 +93,9 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
 		panic("read handler must be set")
 	}
 
-	// [Go] This function was changed to guarantee the requested length size at EOF.
-	// The fact we need to do this is pretty awful, but the description above implies
-	// for that to be the case, and there are tests 
-
 	// If the EOF flag is set and the raw buffer is empty, do nothing.
 	if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
-		// [Go] ACTUALLY! Read the documentation of this function above.
-		// This is just broken. To return true, we need to have the
-		// given length in the buffer. Not doing that means every single
-		// check that calls this function to make sure the buffer has a
-		// given length is Go) panicking; or C) accessing invalid memory.
-		//return true
+		return true
 	}
 
 	// Return if the buffer contains enough characters.
@@ -398,15 +389,6 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
 			break
 		}
 	}
-	// [Go] Read the documentation of this function above. To return true,
-	// we need to have the given length in the buffer. Not doing that means
-	// every single check that calls this function to make sure the buffer
-	// has a given length is Go) panicking; or C) accessing invalid memory.
-	// This happens here due to the EOF above breaking early.
-	for buffer_len < length {
-		parser.buffer[buffer_len] = 0
-		buffer_len++
-	}
 	parser.buffer = parser.buffer[:buffer_len]
 	return true
 }
diff --git a/vendor/gopkg.in/yaml.v2/resolve.go b/vendor/gopkg.in/yaml.v2/resolve.go
index 6c151db6f..93a863274 100644
--- a/vendor/gopkg.in/yaml.v2/resolve.go
+++ b/vendor/gopkg.in/yaml.v2/resolve.go
@@ -3,10 +3,9 @@ package yaml
 import (
 	"encoding/base64"
 	"math"
-	"regexp"
 	"strconv"
 	"strings"
-	"time"
+	"unicode/utf8"
 )
 
 type resolveMapItem struct {
@@ -75,14 +74,12 @@ func longTag(tag string) string {
 
 func resolvableTag(tag string) bool {
 	switch tag {
-	case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
+	case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
 		return true
 	}
 	return false
 }
 
-var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
-
 func resolve(tag string, in string) (rtag string, out interface{}) {
 	if !resolvableTag(tag) {
 		return tag, in
@@ -92,19 +89,6 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 		switch tag {
 		case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
 			return
-		case yaml_FLOAT_TAG:
-			if rtag == yaml_INT_TAG {
-				switch v := out.(type) {
-				case int64:
-					rtag = yaml_FLOAT_TAG
-					out = float64(v)
-					return
-				case int:
-					rtag = yaml_FLOAT_TAG
-					out = float64(v)
-					return
-				}
-			}
 		}
 		failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
 	}()
@@ -138,15 +122,6 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 
 		case 'D', 'S':
 			// Int, float, or timestamp.
-			// Only try values as a timestamp if the value is unquoted or there's an explicit
-			// !!timestamp tag.
-			if tag == "" || tag == yaml_TIMESTAMP_TAG {
-				t, ok := parseTimestamp(in)
-				if ok {
-					return yaml_TIMESTAMP_TAG, t
-				}
-			}
-
 			plain := strings.Replace(in, "_", "", -1)
 			intv, err := strconv.ParseInt(plain, 0, 64)
 			if err == nil {
@@ -160,11 +135,9 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 			if err == nil {
 				return yaml_INT_TAG, uintv
 			}
-			if yamlStyleFloat.MatchString(plain) {
-				floatv, err := strconv.ParseFloat(plain, 64)
-				if err == nil {
-					return yaml_FLOAT_TAG, floatv
-				}
+			floatv, err := strconv.ParseFloat(plain, 64)
+			if err == nil {
+				return yaml_FLOAT_TAG, floatv
 			}
 			if strings.HasPrefix(plain, "0b") {
 				intv, err := strconv.ParseInt(plain[2:], 2, 64)
@@ -180,20 +153,28 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 					return yaml_INT_TAG, uintv
 				}
 			} else if strings.HasPrefix(plain, "-0b") {
-				intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
+				intv, err := strconv.ParseInt(plain[3:], 2, 64)
 				if err == nil {
-					if true || intv == int64(int(intv)) {
-						return yaml_INT_TAG, int(intv)
+					if intv == int64(int(intv)) {
+						return yaml_INT_TAG, -int(intv)
 					} else {
-						return yaml_INT_TAG, intv
+						return yaml_INT_TAG, -intv
 					}
 				}
 			}
+			// XXX Handle timestamps here.
+
 		default:
 			panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
 		}
 	}
-	return yaml_STR_TAG, in
+	if tag == yaml_BINARY_TAG {
+		return yaml_BINARY_TAG, in
+	}
+	if utf8.ValidString(in) {
+		return yaml_STR_TAG, in
+	}
+	return yaml_BINARY_TAG, encodeBase64(in)
 }
 
 // encodeBase64 encodes s as base64 that is broken up into multiple lines
@@ -220,39 +201,3 @@ func encodeBase64(s string) string {
 	}
 	return string(out[:k])
 }
-
-// This is a subset of the formats allowed by the regular expression
-// defined at http://yaml.org/type/timestamp.html.
-var allowedTimestampFormats = []string{
-	"2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
-	"2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
-	"2006-1-2 15:4:5.999999999",       // space separated with no time zone
-	"2006-1-2",                        // date only
-	// Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
-	// from the set of examples.
-}
-
-// parseTimestamp parses s as a timestamp string and
-// returns the timestamp and reports whether it succeeded.
-// Timestamp formats are defined at http://yaml.org/type/timestamp.html
-func parseTimestamp(s string) (time.Time, bool) {
-	// TODO write code to check all the formats supported by
-	// http://yaml.org/type/timestamp.html instead of using time.Parse.
-
-	// Quick check: all date formats start with YYYY-.
-	i := 0
-	for ; i < len(s); i++ {
-		if c := s[i]; c < '0' || c > '9' {
-			break
-		}
-	}
-	if i != 4 || i == len(s) || s[i] != '-' {
-		return time.Time{}, false
-	}
-	for _, format := range allowedTimestampFormats {
-		if t, err := time.Parse(format, s); err == nil {
-			return t, true
-		}
-	}
-	return time.Time{}, false
-}
diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go
index 077fd1dd2..25808000f 100644
--- a/vendor/gopkg.in/yaml.v2/scannerc.go
+++ b/vendor/gopkg.in/yaml.v2/scannerc.go
@@ -9,7 +9,7 @@ import (
 // ************
 //
 // The following notes assume that you are familiar with the YAML specification
-// (http://yaml.org/spec/1.2/spec.html).  We mostly follow it, although in
+// (http://yaml.org/spec/cvs/current.html).  We mostly follow it, although in
 // some cases we are less restrictive that it requires.
 //
 // The process of transforming a YAML stream into a sequence of events is
@@ -611,7 +611,7 @@ func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, co
 	if directive {
 		context = "while parsing a %TAG directive"
 	}
-	return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
+	return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
 }
 
 func trace(args ...interface{}) func() {
@@ -871,6 +871,12 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
 
 	required := parser.flow_level == 0 && parser.indent == parser.mark.column
 
+	// A simple key is required only when it is the first token in the current
+	// line.  Therefore it is always allowed.  But we add a check anyway.
+	if required && !parser.simple_key_allowed {
+		panic("should not happen")
+	}
+
 	//
 	// If the current position may start a simple key, save it.
 	//
@@ -1938,7 +1944,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
 	} else {
 		// It's either the '!' tag or not really a tag handle.  If it's a %TAG
 		// directive, it's an error.  If it's a tag token, it must be a part of URI.
-		if directive && string(s) != "!" {
+		if directive && !(s[0] == '!' && s[1] == 0) {
 			yaml_parser_set_scanner_tag_error(parser, directive,
 				start_mark, "did not find expected '!'")
 			return false
@@ -1953,7 +1959,6 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
 func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
 	//size_t length = head ? strlen((char *)head) : 0
 	var s []byte
-	hasTag := len(head) > 0
 
 	// Copy the head if needed.
 	//
@@ -1995,10 +2000,10 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
 		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
 			return false
 		}
-		hasTag = true
 	}
 
-	if !hasTag {
+	// Check if the tag is non-empty.
+	if len(s) == 0 {
 		yaml_parser_set_scanner_tag_error(parser, directive,
 			start_mark, "did not find expected tag URI")
 		return false
@@ -2469,10 +2474,6 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
 			}
 		}
 
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-
 		// Check if we are at the end of the scalar.
 		if single {
 			if parser.buffer[parser.buffer_pos] == '\'' {
@@ -2485,6 +2486,10 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
 		}
 
 		// Consume blank characters.
+		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+			return false
+		}
+
 		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
 			if is_blank(parser.buffer, parser.buffer_pos) {
 				// Consume a space or a tab character.
@@ -2586,10 +2591,19 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
 		// Consume non-blank characters.
 		for !is_blankz(parser.buffer, parser.buffer_pos) {
 
+			// Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
+			if parser.flow_level > 0 &&
+				parser.buffer[parser.buffer_pos] == ':' &&
+				!is_blankz(parser.buffer, parser.buffer_pos+1) {
+				yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
+					start_mark, "found unexpected ':'")
+				return false
+			}
+
 			// Check for indicators that may end a plain scalar.
 			if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
 				(parser.flow_level > 0 &&
-					(parser.buffer[parser.buffer_pos] == ',' ||
+					(parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
 						parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
 						parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
 						parser.buffer[parser.buffer_pos] == '}')) {
@@ -2641,10 +2655,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
 		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
 			if is_blank(parser.buffer, parser.buffer_pos) {
 
-				// Check for tab characters that abuse indentation.
+				// Check for tab character that abuse indentation.
 				if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
 					yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-						start_mark, "found a tab character that violates indentation")
+						start_mark, "found a tab character that violate indentation")
 					return false
 				}
 
diff --git a/vendor/gopkg.in/yaml.v2/sorter.go b/vendor/gopkg.in/yaml.v2/sorter.go
index 4c45e660a..5958822f9 100644
--- a/vendor/gopkg.in/yaml.v2/sorter.go
+++ b/vendor/gopkg.in/yaml.v2/sorter.go
@@ -51,15 +51,6 @@ func (l keyList) Less(i, j int) bool {
 		}
 		var ai, bi int
 		var an, bn int64
-		if ar[i] == '0' || br[i] == '0' {
-			for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
-				if ar[j] != '0' {
-					an = 1
-					bn = 1
-					break
-				}
-			}
-		}
 		for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
 			an = an*10 + int64(ar[ai]-'0')
 		}
diff --git a/vendor/gopkg.in/yaml.v2/writerc.go b/vendor/gopkg.in/yaml.v2/writerc.go
index a2dde608c..190362f25 100644
--- a/vendor/gopkg.in/yaml.v2/writerc.go
+++ b/vendor/gopkg.in/yaml.v2/writerc.go
@@ -18,9 +18,72 @@ func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
 		return true
 	}
 
-	if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
+	// If the output encoding is UTF-8, we don't need to recode the buffer.
+	if emitter.encoding == yaml_UTF8_ENCODING {
+		if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
+			return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+		}
+		emitter.buffer_pos = 0
+		return true
+	}
+
+	// Recode the buffer into the raw buffer.
+	var low, high int
+	if emitter.encoding == yaml_UTF16LE_ENCODING {
+		low, high = 0, 1
+	} else {
+		high, low = 1, 0
+	}
+
+	pos := 0
+	for pos < emitter.buffer_pos {
+		// See the "reader.c" code for more details on UTF-8 encoding.  Note
+		// that we assume that the buffer contains a valid UTF-8 sequence.
+
+		// Read the next UTF-8 character.
+		octet := emitter.buffer[pos]
+
+		var w int
+		var value rune
+		switch {
+		case octet&0x80 == 0x00:
+			w, value = 1, rune(octet&0x7F)
+		case octet&0xE0 == 0xC0:
+			w, value = 2, rune(octet&0x1F)
+		case octet&0xF0 == 0xE0:
+			w, value = 3, rune(octet&0x0F)
+		case octet&0xF8 == 0xF0:
+			w, value = 4, rune(octet&0x07)
+		}
+		for k := 1; k < w; k++ {
+			octet = emitter.buffer[pos+k]
+			value = (value << 6) + (rune(octet) & 0x3F)
+		}
+		pos += w
+
+		// Write the character.
+		if value < 0x10000 {
+			var b [2]byte
+			b[high] = byte(value >> 8)
+			b[low] = byte(value & 0xFF)
+			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
+		} else {
+			// Write the character using a surrogate pair (check "reader.c").
+			var b [4]byte
+			value -= 0x10000
+			b[high] = byte(0xD8 + (value >> 18))
+			b[low] = byte((value >> 10) & 0xFF)
+			b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
+			b[low+2] = byte(value & 0xFF)
+			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
+		}
+	}
+
+	// Write the raw buffer.
+	if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
 		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
 	}
 	emitter.buffer_pos = 0
+	emitter.raw_buffer = emitter.raw_buffer[:0]
 	return true
 }
diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go
index de85aa4cd..36d6b883a 100644
--- a/vendor/gopkg.in/yaml.v2/yaml.go
+++ b/vendor/gopkg.in/yaml.v2/yaml.go
@@ -9,7 +9,6 @@ package yaml
 import (
 	"errors"
 	"fmt"
-	"io"
 	"reflect"
 	"strings"
 	"sync"
@@ -78,65 +77,8 @@ type Marshaler interface {
 // supported tag options.
 //
 func Unmarshal(in []byte, out interface{}) (err error) {
-	return unmarshal(in, out, false)
-}
-
-// UnmarshalStrict is like Unmarshal except that any fields that are found
-// in the data that do not have corresponding struct members, or mapping
-// keys that are duplicates, will result in
-// an error.
-func UnmarshalStrict(in []byte, out interface{}) (err error) {
-	return unmarshal(in, out, true)
-}
-
-// A Decorder reads and decodes YAML values from an input stream.
-type Decoder struct {
-	strict bool
-	parser *parser
-}
-
-// NewDecoder returns a new decoder that reads from r.
-//
-// The decoder introduces its own buffering and may read
-// data from r beyond the YAML values requested.
-func NewDecoder(r io.Reader) *Decoder {
-	return &Decoder{
-		parser: newParserFromReader(r),
-	}
-}
-
-// SetStrict sets whether strict decoding behaviour is enabled when
-// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
-func (dec *Decoder) SetStrict(strict bool) {
-	dec.strict = strict
-}
-
-// Decode reads the next YAML-encoded value from its input
-// and stores it in the value pointed to by v.
-//
-// See the documentation for Unmarshal for details about the
-// conversion of YAML into a Go value.
-func (dec *Decoder) Decode(v interface{}) (err error) {
-	d := newDecoder(dec.strict)
-	defer handleErr(&err)
-	node := dec.parser.parse()
-	if node == nil {
-		return io.EOF
-	}
-	out := reflect.ValueOf(v)
-	if out.Kind() == reflect.Ptr && !out.IsNil() {
-		out = out.Elem()
-	}
-	d.unmarshal(node, out)
-	if len(d.terrors) > 0 {
-		return &TypeError{d.terrors}
-	}
-	return nil
-}
-
-func unmarshal(in []byte, out interface{}, strict bool) (err error) {
 	defer handleErr(&err)
-	d := newDecoder(strict)
+	d := newDecoder()
 	p := newParser(in)
 	defer p.destroy()
 	node := p.parse()
@@ -157,8 +99,8 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) {
 // of the generated document will reflect the structure of the value itself.
 // Maps and pointers (to struct, string, int, etc) are accepted as the in value.
 //
-// Struct fields are only marshalled if they are exported (have an upper case
-// first letter), and are marshalled using the field name lowercased as the
+// Struct fields are only unmarshalled if they are exported (have an upper case
+// first letter), and are unmarshalled using the field name lowercased as the
 // default key. Custom keys may be defined via the "yaml" name in the field
 // tag: the content preceding the first comma is used as the key, and the
 // following comma-separated options are used to tweak the marshalling process.
@@ -172,10 +114,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) {
 //
 //     omitempty    Only include the field if it's not set to the zero
 //                  value for the type or to empty slices or maps.
-//                  Zero valued structs will be omitted if all their public
-//                  fields are zero, unless they implement an IsZero
-//                  method (see the IsZeroer interface type), in which
-//                  case the field will be included if that method returns true.
+//                  Does not apply to zero valued structs.
 //
 //     flow         Marshal using a flow style (useful for structs,
 //                  sequences and maps).
@@ -190,7 +129,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) {
 // For example:
 //
 //     type T struct {
-//         F int `yaml:"a,omitempty"`
+//         F int "a,omitempty"
 //         B int
 //     }
 //     yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
@@ -200,47 +139,12 @@ func Marshal(in interface{}) (out []byte, err error) {
 	defer handleErr(&err)
 	e := newEncoder()
 	defer e.destroy()
-	e.marshalDoc("", reflect.ValueOf(in))
+	e.marshal("", reflect.ValueOf(in))
 	e.finish()
 	out = e.out
 	return
 }
 
-// An Encoder writes YAML values to an output stream.
-type Encoder struct {
-	encoder *encoder
-}
-
-// NewEncoder returns a new encoder that writes to w.
-// The Encoder should be closed after use to flush all data
-// to w.
-func NewEncoder(w io.Writer) *Encoder {
-	return &Encoder{
-		encoder: newEncoderWithWriter(w),
-	}
-}
-
-// Encode writes the YAML encoding of v to the stream.
-// If multiple items are encoded to the stream, the
-// second and subsequent document will be preceded
-// with a "---" document separator, but the first will not.
-//
-// See the documentation for Marshal for details about the conversion of Go
-// values to YAML.
-func (e *Encoder) Encode(v interface{}) (err error) {
-	defer handleErr(&err)
-	e.encoder.marshalDoc("", reflect.ValueOf(v))
-	return nil
-}
-
-// Close closes the encoder by writing any remaining data.
-// It does not write a stream terminating string "...".
-func (e *Encoder) Close() (err error) {
-	defer handleErr(&err)
-	e.encoder.finish()
-	return nil
-}
-
 func handleErr(err *error) {
 	if v := recover(); v != nil {
 		if e, ok := v.(yamlError); ok {
@@ -296,9 +200,6 @@ type fieldInfo struct {
 	Num       int
 	OmitEmpty bool
 	Flow      bool
-	// Id holds the unique field identifier, so we can cheaply
-	// check for field duplicates without maintaining an extra map.
-	Id int
 
 	// Inline holds the field index if the field is part of an inlined struct.
 	Inline []int
@@ -378,7 +279,6 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 					} else {
 						finfo.Inline = append([]int{i}, finfo.Inline...)
 					}
-					finfo.Id = len(fieldsList)
 					fieldsMap[finfo.Key] = finfo
 					fieldsList = append(fieldsList, finfo)
 				}
@@ -400,16 +300,11 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 			return nil, errors.New(msg)
 		}
 
-		info.Id = len(fieldsList)
 		fieldsList = append(fieldsList, info)
 		fieldsMap[info.Key] = info
 	}
 
-	sinfo = &structInfo{
-		FieldsMap:  fieldsMap,
-		FieldsList: fieldsList,
-		InlineMap:  inlineMap,
-	}
+	sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
 
 	fieldMapMutex.Lock()
 	structMap[st] = sinfo
@@ -417,23 +312,8 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 	return sinfo, nil
 }
 
-// IsZeroer is used to check whether an object is zero to
-// determine whether it should be omitted when marshaling
-// with the omitempty flag. One notable implementation
-// is time.Time.
-type IsZeroer interface {
-	IsZero() bool
-}
-
 func isZero(v reflect.Value) bool {
-	kind := v.Kind()
-	if z, ok := v.Interface().(IsZeroer); ok {
-		if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
-			return true
-		}
-		return z.IsZero()
-	}
-	switch kind {
+	switch v.Kind() {
 	case reflect.String:
 		return len(v.String()) == 0
 	case reflect.Interface, reflect.Ptr:
diff --git a/vendor/gopkg.in/yaml.v2/yamlh.go b/vendor/gopkg.in/yaml.v2/yamlh.go
index e25cee563..d60a6b6b0 100644
--- a/vendor/gopkg.in/yaml.v2/yamlh.go
+++ b/vendor/gopkg.in/yaml.v2/yamlh.go
@@ -1,7 +1,6 @@
 package yaml
 
 import (
-	"fmt"
 	"io"
 )
 
@@ -240,27 +239,6 @@ const (
 	yaml_MAPPING_END_EVENT    // A MAPPING-END event.
 )
 
-var eventStrings = []string{
-	yaml_NO_EVENT:             "none",
-	yaml_STREAM_START_EVENT:   "stream start",
-	yaml_STREAM_END_EVENT:     "stream end",
-	yaml_DOCUMENT_START_EVENT: "document start",
-	yaml_DOCUMENT_END_EVENT:   "document end",
-	yaml_ALIAS_EVENT:          "alias",
-	yaml_SCALAR_EVENT:         "scalar",
-	yaml_SEQUENCE_START_EVENT: "sequence start",
-	yaml_SEQUENCE_END_EVENT:   "sequence end",
-	yaml_MAPPING_START_EVENT:  "mapping start",
-	yaml_MAPPING_END_EVENT:    "mapping end",
-}
-
-func (e yaml_event_type_t) String() string {
-	if e < 0 || int(e) >= len(eventStrings) {
-		return fmt.Sprintf("unknown event %d", e)
-	}
-	return eventStrings[e]
-}
-
 // The event structure.
 type yaml_event_t struct {
 
@@ -530,7 +508,7 @@ type yaml_parser_t struct {
 
 	problem string // Error description.
 
-	// The byte about which the problem occurred.
+	// The byte about which the problem occured.
 	problem_offset int
 	problem_value  int
 	problem_mark   yaml_mark_t
@@ -543,9 +521,9 @@ type yaml_parser_t struct {
 
 	read_handler yaml_read_handler_t // Read handler.
 
-	input_reader io.Reader // File input data.
-	input        []byte    // String input data.
-	input_pos    int
+	input_file io.Reader // File input data.
+	input      []byte    // String input data.
+	input_pos  int
 
 	eof bool // EOF flag
 
@@ -654,7 +632,7 @@ type yaml_emitter_t struct {
 	write_handler yaml_write_handler_t // Write handler.
 
 	output_buffer *[]byte   // String output data.
-	output_writer io.Writer // File output data.
+	output_file   io.Writer // File output data.
 
 	buffer     []byte // The working buffer.
 	buffer_pos int    // The current position of the buffer.