You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafficcontrol.apache.org by GitBox <gi...@apache.org> on 2018/11/19 18:00:10 UTC

[GitHub] mitchell852 closed pull request #2999: Change Monitor to third-party JSON, for performance

mitchell852 closed pull request #2999: Change Monitor to third-party JSON, for performance
URL: https://github.com/apache/trafficcontrol/pull/2999
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/.rat-excludes b/.rat-excludes
index 0f9e81796..22972180f 100644
--- a/.rat-excludes
+++ b/.rat-excludes
@@ -75,3 +75,6 @@ bbolt(?:                             MIT. Properly documented in LICENSE ){0}
 miekg(?:                             BSD 3-clause. Properly documented in LICENSE ){0}
 angular-chart(?:                     BSD 2-clause. Properly documented in LICENSE ){0}
 chartjs(?:                           MIT. Properly documented in LICENSE ){0}
+json-iterator/go(?:                  MIT. Properly documented in LICENSE ){0}
+modern-go/concurrent(?:              Apache 2.0. Properly documented in LICENSE ){0}
+modern-go/reflect2(?:                Apache 2.0. Properly documented in LICENSE ){0}
diff --git a/LICENSE b/LICENSE
index ba2dc9b5d..0400aa499 100644
--- a/LICENSE
+++ b/LICENSE
@@ -429,3 +429,15 @@ The asn1-ber.v1 component is used under the MIT license:
 The ldap.v2 component is used under the MIT license:
 @traffic_ops/vendor/gopkg.in/ldap.v2/*
 ./traffic_ops/vendor/gopkg.in/ldap.v2/LICENSE
+
+The json-iterator/go component is used under the MIT license:
+@vendor/github.com/json-iterator/go/*
+./vendor/github.com/json-iterator/go/LICENSE
+
+The modern-go/concurrent component is used under the Apache 2.0 license:
+@vendor/github.com/modern-go/concurrent/*
+./vendor/github.com/modern-go/concurrent/LICENSE
+
+The modern-go/reflect2 component is used under the Apache 2.0 license:
+@vendor/github.com/modern-go/reflect2/*
+./vendor/github.com/modern-go/reflect2/LICENSE
diff --git a/traffic_monitor/cache/astats.go b/traffic_monitor/cache/astats.go
index 1d47a0988..763de44bb 100644
--- a/traffic_monitor/cache/astats.go
+++ b/traffic_monitor/cache/astats.go
@@ -19,10 +19,6 @@ package cache
  * under the License.
  */
 
-import (
-	"encoding/json"
-)
-
 // Astats contains ATS data returned from the Astats ATS plugin. This includes generic stats, as well as fixed system stats.
 type Astats struct {
 	Ats    map[string]interface{} `json:"ats"`
@@ -43,13 +39,6 @@ type AstatsSystem struct {
 	NotAvailable      bool   `json:"notAvailable,omitempty"`
 }
 
-// Unmarshal unmarshalls the given bytes, which must be JSON Astats data, into an Astats object.
-func Unmarshal(body []byte) (Astats, error) {
-	var aStats Astats
-	err := json.Unmarshal(body, &aStats)
-	return aStats, err
-}
-
 type AStat struct {
 	InBytes   uint64
 	OutBytes  uint64
diff --git a/traffic_monitor/cache/astats_test.go b/traffic_monitor/cache/astats_test.go
index 7cd3b5256..d9896decf 100644
--- a/traffic_monitor/cache/astats_test.go
+++ b/traffic_monitor/cache/astats_test.go
@@ -28,6 +28,8 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
+
+	"github.com/json-iterator/go"
 )
 
 func TestAstats(t *testing.T) {
@@ -37,7 +39,9 @@ func TestAstats(t *testing.T) {
 	if err != nil {
 		t.Log(err)
 	}
-	aStats, err := Unmarshal(text)
+	aStats := Astats{}
+	json := jsoniter.ConfigFastest
+	err = json.Unmarshal(text, &aStats)
 	fmt.Printf("aStats ---> %v\n", aStats)
 	if err != nil {
 		t.Log(err)
diff --git a/traffic_monitor/cache/data.go b/traffic_monitor/cache/data.go
index c23dc970d..83854361a 100644
--- a/traffic_monitor/cache/data.go
+++ b/traffic_monitor/cache/data.go
@@ -20,11 +20,12 @@ package cache
  */
 
 import (
-	"encoding/json"
 	"fmt"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+
+	"github.com/json-iterator/go"
 )
 
 // AvailableStatusReported is the status string returned by caches set to "reported" in Traffic Ops.
@@ -91,6 +92,7 @@ func (t *ResultStatVal) MarshalJSON() ([]byte, error) {
 		Time: t.Time.UnixNano() / 1000000, // ms since the epoch
 		Span: t.Span,
 	}
+	json := jsoniter.ConfigFastest // TODO make configurable
 	return json.Marshal(&v)
 }
 
diff --git a/traffic_monitor/cache/stats_type_astats.go b/traffic_monitor/cache/stats_type_astats.go
index 29419d1f0..80930d458 100644
--- a/traffic_monitor/cache/stats_type_astats.go
+++ b/traffic_monitor/cache/stats_type_astats.go
@@ -29,7 +29,6 @@ package cache
 //   `in_bytes`, `out_bytes`, `status_2xx`, `status_3xx`, `status_4xx`, `status_5xx`
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
@@ -40,6 +39,7 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_monitor/dsdata"
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
+	"github.com/json-iterator/go"
 )
 
 func init() {
@@ -52,6 +52,8 @@ func astatsParse(cache tc.CacheName, rdr io.Reader) (error, map[string]interface
 		return errors.New("handler got nil reader"), nil, AstatsSystem{}
 	}
 	astats := Astats{}
+
+	json := jsoniter.ConfigFastest // TODo make configurable?
 	err := json.NewDecoder(rdr).Decode(&astats)
 	return err, astats.Ats, astats.System
 }
diff --git a/traffic_monitor/config/config.go b/traffic_monitor/config/config.go
index 6cecdd301..c64d250b1 100644
--- a/traffic_monitor/config/config.go
+++ b/traffic_monitor/config/config.go
@@ -20,11 +20,12 @@ package config
  */
 
 import (
-	"encoding/json"
 	"io/ioutil"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-log"
+
+	"github.com/json-iterator/go"
 )
 
 // LogLocation is a location to log to. This may be stdout, stderr, null (/dev/null), or a valid file path.
@@ -104,6 +105,7 @@ var DefaultConfig = Config{
 // MarshalJSON marshals custom millisecond durations. Aliasing inspired by http://choly.ca/post/go-json-marshalling/
 func (c *Config) MarshalJSON() ([]byte, error) {
 	type Alias Config
+	json := jsoniter.ConfigFastest // TODO make configurable?
 	return json.Marshal(&struct {
 		CacheHealthPollingIntervalMs   uint64 `json:"cache_health_polling_interval_ms"`
 		CacheStatPollingIntervalMs     uint64 `json:"cache_stat_polling_interval_ms"`
@@ -149,6 +151,7 @@ func (c *Config) UnmarshalJSON(data []byte) error {
 	}{
 		Alias: (*Alias)(c),
 	}
+	json := jsoniter.ConfigFastest // TODO make configurable?
 	if err := json.Unmarshal(data, &aux); err != nil {
 		return err
 	}
@@ -208,6 +211,7 @@ func Load(fileName string) (Config, error) {
 // LoadBytes loads the given file bytes.
 func LoadBytes(bytes []byte) (Config, error) {
 	cfg := DefaultConfig
+	json := jsoniter.ConfigFastest // TODO make configurable?
 	err := json.Unmarshal(bytes, &cfg)
 	return cfg, err
 }
diff --git a/traffic_monitor/datareq/cachestate.go b/traffic_monitor/datareq/cachestate.go
index 0f87f6cc0..f741be1d7 100644
--- a/traffic_monitor/datareq/cachestate.go
+++ b/traffic_monitor/datareq/cachestate.go
@@ -20,7 +20,6 @@
 package datareq
 
 import (
-	"encoding/json"
 	"fmt"
 	"time"
 
@@ -32,6 +31,8 @@ import (
 	"github.com/apache/trafficcontrol/traffic_monitor/peer"
 	"github.com/apache/trafficcontrol/traffic_monitor/threadsafe"
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
+
+	"github.com/json-iterator/go"
 )
 
 // CacheStatus contains summary stat data about the given cache.
@@ -68,6 +69,7 @@ func srvAPICacheStates(
 	statMaxKbpses threadsafe.CacheKbpses,
 	monitorConfig threadsafe.TrafficMonitorConfigMap,
 ) ([]byte, error) {
+	json := jsoniter.ConfigFastest
 	return json.Marshal(createCacheStatuses(toData.Get().ServerTypes, statInfoHistory.Get(), statResultHistory, healthHistory.Get(), lastHealthDurations.Get(), localStates.Get().Caches, lastStats.Get(), localCacheStatus, statMaxKbpses, monitorConfig.Get().TrafficServer))
 }
 
diff --git a/traffic_monitor/datareq/configdoc.go b/traffic_monitor/datareq/configdoc.go
index 5d759f6b0..3fa930ad5 100644
--- a/traffic_monitor/datareq/configdoc.go
+++ b/traffic_monitor/datareq/configdoc.go
@@ -20,9 +20,9 @@
 package datareq
 
 import (
-	"encoding/json"
-
 	"github.com/apache/trafficcontrol/traffic_monitor/threadsafe"
+
+	"github.com/json-iterator/go"
 )
 
 func srvConfigDoc(opsConfig threadsafe.OpsConfig) ([]byte, error) {
@@ -31,5 +31,6 @@ func srvConfigDoc(opsConfig threadsafe.OpsConfig) ([]byte, error) {
 	if opsConfigCopy.Password != "" {
 		opsConfigCopy.Password = "*****"
 	}
+	json := jsoniter.ConfigFastest
 	return json.Marshal(opsConfigCopy)
 }
diff --git a/traffic_monitor/datareq/crconfighist.go b/traffic_monitor/datareq/crconfighist.go
index 5e8e3530f..b807b5556 100644
--- a/traffic_monitor/datareq/crconfighist.go
+++ b/traffic_monitor/datareq/crconfighist.go
@@ -20,11 +20,12 @@
 package datareq
 
 import (
-	"encoding/json"
-
 	"github.com/apache/trafficcontrol/traffic_monitor/towrap"
+
+	"github.com/json-iterator/go"
 )
 
 func srvAPICRConfigHist(toc towrap.ITrafficOpsSession) ([]byte, error) {
+	json := jsoniter.ConfigFastest
 	return json.Marshal(toc.CRConfigHistory())
 }
diff --git a/traffic_monitor/datareq/dsstat.go b/traffic_monitor/datareq/dsstat.go
index 5dd902776..3b5afccdf 100644
--- a/traffic_monitor/datareq/dsstat.go
+++ b/traffic_monitor/datareq/dsstat.go
@@ -20,12 +20,13 @@
 package datareq
 
 import (
-	"encoding/json"
 	"net/http"
 	"net/url"
 
 	"github.com/apache/trafficcontrol/traffic_monitor/threadsafe"
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
+
+	"github.com/json-iterator/go"
 )
 
 func srvDSStats(params url.Values, errorCount threadsafe.Uint, path string, toData todata.TODataThreadsafe, dsStats threadsafe.DSStatsReader) ([]byte, int) {
@@ -34,6 +35,7 @@ func srvDSStats(params url.Values, errorCount threadsafe.Uint, path string, toDa
 		HandleErr(errorCount, path, err)
 		return []byte(err.Error()), http.StatusBadRequest
 	}
+	json := jsoniter.ConfigFastest
 	bytes, err := json.Marshal(dsStats.Get().JSON(filter, params))
 	return WrapErrCode(errorCount, path, bytes, err)
 }
diff --git a/traffic_monitor/datareq/eventlog.go b/traffic_monitor/datareq/eventlog.go
index c5c47f98d..08860c9b5 100644
--- a/traffic_monitor/datareq/eventlog.go
+++ b/traffic_monitor/datareq/eventlog.go
@@ -20,9 +20,9 @@
 package datareq
 
 import (
-	"encoding/json"
-
 	"github.com/apache/trafficcontrol/traffic_monitor/health"
+
+	"github.com/json-iterator/go"
 )
 
 // JSONEvents represents the structure we wish to serialize to JSON, for Events.
@@ -31,5 +31,6 @@ type JSONEvents struct {
 }
 
 func srvEventLog(events health.ThreadsafeEvents) ([]byte, error) {
+	json := jsoniter.ConfigFastest
 	return json.Marshal(JSONEvents{Events: events.Get()})
 }
diff --git a/traffic_monitor/datareq/monitorconfig.go b/traffic_monitor/datareq/monitorconfig.go
index a719b7f3c..56cc5d3ce 100644
--- a/traffic_monitor/datareq/monitorconfig.go
+++ b/traffic_monitor/datareq/monitorconfig.go
@@ -20,11 +20,12 @@
 package datareq
 
 import (
-	"encoding/json"
-
 	"github.com/apache/trafficcontrol/traffic_monitor/threadsafe"
+
+	"github.com/json-iterator/go"
 )
 
 func srvMonitorConfig(mcThs threadsafe.TrafficMonitorConfigMap) ([]byte, error) {
+	json := jsoniter.ConfigFastest
 	return json.Marshal(mcThs.Get())
 }
diff --git a/traffic_monitor/datareq/peerstate.go b/traffic_monitor/datareq/peerstate.go
index 31d9a78b7..32c0a0b64 100644
--- a/traffic_monitor/datareq/peerstate.go
+++ b/traffic_monitor/datareq/peerstate.go
@@ -20,7 +20,6 @@
 package datareq
 
 import (
-	"encoding/json"
 	"net/http"
 	"net/url"
 	"time"
@@ -30,6 +29,8 @@ import (
 	"github.com/apache/trafficcontrol/traffic_monitor/srvhttp"
 	"github.com/apache/trafficcontrol/traffic_monitor/threadsafe"
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
+
+	"github.com/json-iterator/go"
 )
 
 // APIPeerStates contains the data to be returned for an API call to get the peer states of a Traffic Monitor. This contains common API data returned by most endpoints, and a map of peers, to caches' states.
@@ -49,6 +50,7 @@ func srvPeerStates(params url.Values, errorCount threadsafe.Uint, path string, t
 		HandleErr(errorCount, path, err)
 		return []byte(err.Error()), http.StatusBadRequest
 	}
+	json := jsoniter.ConfigFastest
 	bytes, err := json.Marshal(createAPIPeerStates(peerStates.GetCrstates(), peerStates.GetPeersOnline(), filter, params))
 	return WrapErrCode(errorCount, path, bytes, err)
 }
diff --git a/traffic_monitor/datareq/stat.go b/traffic_monitor/datareq/stat.go
index a0d80cb03..31b0b1722 100644
--- a/traffic_monitor/datareq/stat.go
+++ b/traffic_monitor/datareq/stat.go
@@ -20,7 +20,6 @@
 package datareq
 
 import (
-	"encoding/json"
 	"math"
 	"runtime"
 	"sort"
@@ -31,6 +30,8 @@ import (
 	"github.com/apache/trafficcontrol/traffic_monitor/config"
 	"github.com/apache/trafficcontrol/traffic_monitor/peer"
 	"github.com/apache/trafficcontrol/traffic_monitor/threadsafe"
+
+	"github.com/json-iterator/go"
 )
 
 type JSONStats struct {
@@ -107,6 +108,7 @@ func getStats(staticAppData config.StaticAppData, pollingInterval time.Duration,
 
 	s.QueryInterval95thPercentile = getCacheTimePercentile(lastHealthTimes, 0.95).Nanoseconds() / util.MSPerNS
 
+	json := jsoniter.ConfigDefault
 	return json.Marshal(JSONStats{Stats: s})
 }
 
diff --git a/traffic_monitor/datareq/stat_test.go b/traffic_monitor/datareq/stat_test.go
index 82b6f02fb..0ca5663ee 100644
--- a/traffic_monitor/datareq/stat_test.go
+++ b/traffic_monitor/datareq/stat_test.go
@@ -20,7 +20,6 @@ package datareq
  */
 
 import (
-	"encoding/json"
 	"errors"
 	"math"
 	"math/rand"
@@ -31,6 +30,8 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_monitor/config"
 	"github.com/apache/trafficcontrol/traffic_monitor/peer"
+
+	"github.com/json-iterator/go"
 )
 
 func getMockStaticAppData() config.StaticAppData {
@@ -149,6 +150,7 @@ func TestGetStats(t *testing.T) {
 	}
 
 	jsonStats := JSONStats{}
+	json := jsoniter.ConfigFastest // TODO make configurable
 	if err := json.Unmarshal(statsBts, &jsonStats); err != nil {
 		t.Fatalf("expected getStats bytes: Stats JSON, actual: error decoding: %+v\n", err)
 	}
diff --git a/traffic_monitor/datareq/statsummary.go b/traffic_monitor/datareq/statsummary.go
index 85822ff5f..e3c31b3c9 100644
--- a/traffic_monitor/datareq/statsummary.go
+++ b/traffic_monitor/datareq/statsummary.go
@@ -20,7 +20,6 @@
 package datareq
 
 import (
-	"encoding/json"
 	"net/http"
 	"net/url"
 	"time"
@@ -32,6 +31,8 @@ import (
 	"github.com/apache/trafficcontrol/traffic_monitor/srvhttp"
 	"github.com/apache/trafficcontrol/traffic_monitor/threadsafe"
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
+
+	"github.com/json-iterator/go"
 )
 
 type StatSummary struct {
@@ -56,6 +57,8 @@ func srvStatSummary(params url.Values, errorCount threadsafe.Uint, path string,
 		HandleErr(errorCount, path, err)
 		return []byte(err.Error()), http.StatusBadRequest
 	}
+
+	json := jsoniter.ConfigFastest
 	bytes, err := json.Marshal(createStatSummary(statResultHistory, filter, params))
 	return WrapErrCode(errorCount, path, bytes, err)
 }
diff --git a/traffic_monitor/manager/opsconfig.go b/traffic_monitor/manager/opsconfig.go
index fbd0dae3c..7b34bcd25 100644
--- a/traffic_monitor/manager/opsconfig.go
+++ b/traffic_monitor/manager/opsconfig.go
@@ -20,7 +20,6 @@ package manager
  */
 
 import (
-	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"net"
@@ -40,6 +39,8 @@ import (
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
 	"github.com/apache/trafficcontrol/traffic_monitor/towrap"
 	to "github.com/apache/trafficcontrol/traffic_ops/client"
+
+	"github.com/json-iterator/go"
 )
 
 // StartOpsConfigManager starts the ops config manager goroutine, returning the (threadsafe) variables which it sets.
@@ -88,6 +89,7 @@ func StartOpsConfigManager(
 		}
 
 		newOpsConfig := handler.OpsConfig{}
+		json := jsoniter.ConfigFastest // TODO make configurable?
 		if err = json.Unmarshal(bytes, &newOpsConfig); err != nil {
 			handleErr(fmt.Errorf("Could not unmarshal Ops Config JSON: %s\n", err))
 			return
diff --git a/traffic_monitor/peer/peer.go b/traffic_monitor/peer/peer.go
index bc7f7ed54..df9134986 100644
--- a/traffic_monitor/peer/peer.go
+++ b/traffic_monitor/peer/peer.go
@@ -20,11 +20,12 @@ package peer
  */
 
 import (
-	"encoding/json"
 	"io"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+
+	"github.com/json-iterator/go"
 )
 
 // Handler handles peer Traffic Monitor data, taking a raw reader, parsing the data, and passing a result object to the ResultChannel. This fulfills the common `Handler` interface.
@@ -64,9 +65,8 @@ func (handler Handler) Handle(id string, r io.Reader, format string, reqTime tim
 	}
 
 	if r != nil {
-		dec := json.NewDecoder(r)
-		err = dec.Decode(&result.PeerStates)
-
+		json := jsoniter.ConfigFastest // TODo make configurable?
+		err = json.NewDecoder(r).Decode(&result.PeerStates)
 		if err == nil {
 			result.Available = true
 		} else {
diff --git a/traffic_monitor/threadsafe/resultstathistory.go b/traffic_monitor/threadsafe/resultstathistory.go
index 05b679318..94256e587 100644
--- a/traffic_monitor/threadsafe/resultstathistory.go
+++ b/traffic_monitor/threadsafe/resultstathistory.go
@@ -21,7 +21,6 @@ package threadsafe
  */
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	"net/url"
@@ -32,6 +31,7 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_monitor/cache"
 	"github.com/apache/trafficcontrol/traffic_monitor/srvhttp"
+	"github.com/json-iterator/go"
 )
 
 // ResultStatHistory provides safe access for multiple goroutines readers and a single writer to a stored HistoryHistory object.
@@ -247,6 +247,7 @@ func StatsMarshall(statResultHistory ResultStatHistory, statInfo cache.ResultInf
 		}
 	}
 
+	json := jsoniter.ConfigFastest // TODO make configurable
 	return json.Marshal(stats)
 }
 
diff --git a/traffic_monitor/threadsafe/resultstathistory_test.go b/traffic_monitor/threadsafe/resultstathistory_test.go
index ab6f21625..51c66b496 100644
--- a/traffic_monitor/threadsafe/resultstathistory_test.go
+++ b/traffic_monitor/threadsafe/resultstathistory_test.go
@@ -20,7 +20,6 @@ package threadsafe
  */
 
 import (
-	"encoding/json"
 	"fmt"
 	"math/rand"
 	"net/url"
@@ -30,6 +29,8 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_monitor/cache"
 	"github.com/apache/trafficcontrol/traffic_monitor/srvhttp"
+
+	"github.com/json-iterator/go"
 )
 
 func randResultStatHistory() ResultStatHistory {
@@ -147,6 +148,7 @@ func TestStatsMarshall(t *testing.T) {
 	// }
 
 	stats := cache.Stats{}
+	json := jsoniter.ConfigFastest // TODO make configurable
 	if err := json.Unmarshal(bytes, &stats); err != nil {
 		t.Fatalf("unmarshalling expected nil err, actual err: %v", err)
 	}
diff --git a/traffic_monitor/tmcheck/dsstats.go b/traffic_monitor/tmcheck/dsstats.go
index e5119f8f6..d9479db9b 100644
--- a/traffic_monitor/tmcheck/dsstats.go
+++ b/traffic_monitor/tmcheck/dsstats.go
@@ -20,13 +20,14 @@
 package tmcheck
 
 import (
-	"encoding/json"
 	"fmt"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_monitor/dsdata"
 	to "github.com/apache/trafficcontrol/traffic_ops/client"
+
+	"github.com/json-iterator/go"
 )
 
 // ValidateDSStates validates that all Delivery Services in the CRConfig exist in given Traffic Monitor's DSStats.
@@ -47,6 +48,7 @@ func ValidateDSStatsWithCDN(tmURI string, tmCDN string, toClient *to.Session) er
 	}
 
 	crConfig := tc.CRConfig{}
+	json := jsoniter.ConfigFastest
 	if err := json.Unmarshal(crConfigBytes, &crConfig); err != nil {
 		return fmt.Errorf("unmarshalling CRConfig JSON: %v", err)
 	}
diff --git a/traffic_monitor/tmcheck/offlinestates.go b/traffic_monitor/tmcheck/offlinestates.go
index b37017ed0..599e3d597 100644
--- a/traffic_monitor/tmcheck/offlinestates.go
+++ b/traffic_monitor/tmcheck/offlinestates.go
@@ -20,12 +20,13 @@
 package tmcheck
 
 import (
-	"encoding/json"
 	"fmt"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	to "github.com/apache/trafficcontrol/traffic_ops/client"
+
+	"github.com/json-iterator/go"
 )
 
 // ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
@@ -45,6 +46,7 @@ func ValidateOfflineStatesWithCDN(tmURI string, tmCDN string, toClient *to.Sessi
 	}
 
 	crConfig := tc.CRConfig{}
+	json := jsoniter.ConfigFastest
 	if err := json.Unmarshal(crConfigBytes, &crConfig); err != nil {
 		return fmt.Errorf("unmarshalling CRConfig JSON: %v", err)
 	}
diff --git a/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor/tmcheck/tmcheck.go
index 039ac88ff..4561f9320 100644
--- a/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor/tmcheck/tmcheck.go
@@ -22,7 +22,6 @@ package tmcheck
 
 import (
 	"crypto/tls"
-	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"net/http"
@@ -32,6 +31,8 @@ import (
 	"github.com/apache/trafficcontrol/traffic_monitor/datareq"
 	"github.com/apache/trafficcontrol/traffic_monitor/dsdata"
 	to "github.com/apache/trafficcontrol/traffic_ops/client"
+
+	"github.com/json-iterator/go"
 )
 
 const RequestTimeout = time.Second * time.Duration(30)
@@ -66,6 +67,7 @@ func GetCDN(uri string) (string, error) {
 	}
 
 	configDoc := TrafficMonitorConfigDoc{}
+	json := jsoniter.ConfigFastest
 	if err := json.Unmarshal(respBytes, &configDoc); err != nil {
 		return "", fmt.Errorf("unmarshalling: %v", err)
 	}
@@ -85,6 +87,7 @@ func GetCRStates(uri string) (*tc.CRStates, error) {
 	}
 
 	states := tc.CRStates{}
+	json := jsoniter.ConfigFastest
 	if err := json.Unmarshal(respBytes, &states); err != nil {
 		return nil, fmt.Errorf("unmarshalling: %v", err)
 	}
@@ -104,6 +107,7 @@ func GetDSStats(uri string) (*dsdata.StatsOld, error) {
 	}
 
 	dsStats := dsdata.StatsOld{}
+	json := jsoniter.ConfigFastest
 	if err := json.Unmarshal(respBytes, &dsStats); err != nil {
 		return nil, fmt.Errorf("unmarshalling: %v", err)
 	}
@@ -123,6 +127,7 @@ func GetStats(uri string) (*datareq.Stats, error) {
 	}
 
 	stats := datareq.JSONStats{}
+	json := jsoniter.ConfigFastest
 	if err := json.Unmarshal(respBytes, &stats); err != nil {
 		return nil, fmt.Errorf("unmarshalling: %v", err)
 	}
@@ -290,6 +295,7 @@ func GetCRConfigs(cdns map[tc.CDNName]struct{}, toClient *to.Session) map[tc.CDN
 		}
 
 		crConfig := tc.CRConfig{}
+		json := jsoniter.ConfigFastest
 		if err := json.Unmarshal(crConfigBytes, &crConfig); err != nil {
 			crConfigs[cdn] = CRConfigOrError{Err: fmt.Errorf("unmarshalling CRConfig JSON: %v", err)}
 		}
diff --git a/traffic_monitor/todata/todata.go b/traffic_monitor/todata/todata.go
index 680e4e38b..819d56392 100644
--- a/traffic_monitor/todata/todata.go
+++ b/traffic_monitor/todata/todata.go
@@ -20,7 +20,6 @@ package todata
  */
 
 import (
-	"encoding/json"
 	"fmt"
 	"regexp"
 	"strings"
@@ -29,6 +28,8 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-log"
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_monitor/towrap"
+
+	"github.com/json-iterator/go"
 )
 
 // Regexes maps Delivery Service Regular Expressions to delivery services.
@@ -150,6 +151,7 @@ func (d TODataThreadsafe) Update(to towrap.ITrafficOpsSession, cdn string) error
 	newTOData := TOData{}
 
 	var crConfig CRConfig
+	json := jsoniter.ConfigFastest
 	err = json.Unmarshal(crConfigBytes, &crConfig)
 	if err != nil {
 		return fmt.Errorf("Error unmarshalling CRconfig: %v", err)
diff --git a/traffic_monitor/towrap/towrap.go b/traffic_monitor/towrap/towrap.go
index 36e148c08..a017945b4 100644
--- a/traffic_monitor/towrap/towrap.go
+++ b/traffic_monitor/towrap/towrap.go
@@ -20,7 +20,6 @@ package towrap
  */
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	"strconv"
@@ -30,6 +29,8 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-log"
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_ops/client"
+
+	"github.com/json-iterator/go"
 )
 
 // ITrafficOpsSession provides an interface to the Traffic Ops client, so it may be wrapped or mocked.
@@ -242,6 +243,7 @@ func (s TrafficOpsSessionThreadsafe) CRConfigRaw(cdn string) ([]byte, error) {
 	}
 
 	crc := &tc.CRConfig{}
+	json := jsoniter.ConfigFastest
 	if err = json.Unmarshal(b, crc); err != nil {
 		err = errors.New("invalid JSON: " + err.Error())
 		hist.Err = err
@@ -292,6 +294,7 @@ func (s TrafficOpsSessionThreadsafe) TrafficMonitorConfigMap(cdn string) (*tc.Tr
 	}
 
 	crConfig := tc.CRConfig{}
+	json := jsoniter.ConfigFastest
 	if err := json.Unmarshal(crcData, &crConfig); err != nil {
 		return nil, fmt.Errorf("unmarshalling CRConfig JSON : %v", err)
 	}
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/.travis.yml b/vendor/github.com/json-iterator/go/.travis.yml
new file mode 100644
index 000000000..449e67cd0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+
+go:
+  - 1.8.x
+  - 1.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/Gopkg.lock b/vendor/github.com/json-iterator/go/Gopkg.lock
new file mode 100644
index 000000000..c8a9fbb38
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/Gopkg.lock
@@ -0,0 +1,21 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+  name = "github.com/modern-go/concurrent"
+  packages = ["."]
+  revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a"
+  version = "1.0.0"
+
+[[projects]]
+  name = "github.com/modern-go/reflect2"
+  packages = ["."]
+  revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
+  version = "1.0.1"
+
+[solve-meta]
+  analyzer-name = "dep"
+  analyzer-version = 1
+  inputs-digest = "ea54a775e5a354cb015502d2e7aa4b74230fc77e894f34a838b268c25ec8eeb8"
+  solver-name = "gps-cdcl"
+  solver-version = 1
diff --git a/vendor/github.com/json-iterator/go/Gopkg.toml b/vendor/github.com/json-iterator/go/Gopkg.toml
new file mode 100644
index 000000000..313a0f887
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/Gopkg.toml
@@ -0,0 +1,26 @@
+# 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"
+
+ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"]
+
+[[constraint]]
+  name = "github.com/modern-go/reflect2"
+  version = "1.0.1"
diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/json-iterator/go/LICENSE
new file mode 100644
index 000000000..2cf4f5ab2
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 json-iterator
+
+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/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md
new file mode 100644
index 000000000..54d5afe95
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/README.md
@@ -0,0 +1,91 @@
+[![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"
+
+You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go)
+
+```
+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 |
+
+Always benchmark with your own workload. 
+The result depends heavily on the data input.
+
+# Usage
+
+100% compatibility with standard lib
+
+Replace
+
+```go
+import "encoding/json"
+json.Marshal(&data)
+```
+
+with 
+
+```go
+import "github.com/json-iterator/go"
+
+var json = jsoniter.ConfigCompatibleWithStandardLibrary
+json.Marshal(&data)
+```
+
+Replace
+
+```go
+import "encoding/json"
+json.Unmarshal(input, &data)
+```
+
+with
+
+```go
+import "github.com/json-iterator/go"
+
+var json = jsoniter.ConfigCompatibleWithStandardLibrary
+json.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)
+* [Oleg Shaldybin](https://github.com/olegshaldybin)
+* [Jason Toffaletti](https://github.com/toffaletti)
+
+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/adapter.go b/vendor/github.com/json-iterator/go/adapter.go
new file mode 100644
index 000000000..e674d0f39
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/adapter.go
@@ -0,0 +1,150 @@
+package jsoniter
+
+import (
+	"bytes"
+	"io"
+)
+
+// RawMessage to make replace json with jsoniter
+type RawMessage []byte
+
+// Unmarshal adapts to json/encoding Unmarshal API
+//
+// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
+// Refer to https://godoc.org/encoding/json#Unmarshal for more information
+func Unmarshal(data []byte, v interface{}) error {
+	return ConfigDefault.Unmarshal(data, v)
+}
+
+// UnmarshalFromString convenient method to read from string instead of []byte
+func UnmarshalFromString(str string, v interface{}) error {
+	return ConfigDefault.UnmarshalFromString(str, v)
+}
+
+// Get quick method to get value from deeply nested JSON structure
+func Get(data []byte, path ...interface{}) Any {
+	return ConfigDefault.Get(data, path...)
+}
+
+// Marshal adapts to json/encoding Marshal API
+//
+// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API
+// Refer to https://godoc.org/encoding/json#Marshal for more information
+func Marshal(v interface{}) ([]byte, error) {
+	return ConfigDefault.Marshal(v)
+}
+
+// MarshalIndent same as json.MarshalIndent. Prefix is not supported.
+func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
+	return ConfigDefault.MarshalIndent(v, prefix, indent)
+}
+
+// MarshalToString convenient method to write as string instead of []byte
+func MarshalToString(v interface{}) (string, error) {
+	return ConfigDefault.MarshalToString(v)
+}
+
+// NewDecoder adapts to json/stream NewDecoder API.
+//
+// NewDecoder returns a new decoder that reads from r.
+//
+// Instead of a json/encoding Decoder, an Decoder is returned
+// Refer to https://godoc.org/encoding/json#NewDecoder for more information
+func NewDecoder(reader io.Reader) *Decoder {
+	return ConfigDefault.NewDecoder(reader)
+}
+
+// Decoder reads and decodes JSON values from an input stream.
+// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress)
+type Decoder struct {
+	iter *Iterator
+}
+
+// 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 {
+		return nil
+	}
+	return adapter.iter.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 != '}'
+}
+
+// Buffered remaining buffer
+func (adapter *Decoder) Buffered() io.Reader {
+	remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail]
+	return bytes.NewReader(remaining)
+}
+
+// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
+// Number instead of as a float64.
+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)
+}
+
+// NewEncoder same as json.NewEncoder
+func NewEncoder(writer io.Writer) *Encoder {
+	return ConfigDefault.NewEncoder(writer)
+}
+
+// Encoder same as json.Encoder
+type Encoder struct {
+	stream *Stream
+}
+
+// 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)
+}
+
+// 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)
+}
diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/any.go
new file mode 100644
index 000000000..f6b8aeab0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any.go
@@ -0,0 +1,325 @@
+package jsoniter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"io"
+	"reflect"
+	"strconv"
+	"unsafe"
+)
+
+// Any generic object representation.
+// The lazy json implementation holds []byte and parse lazily.
+type Any interface {
+	LastError() error
+	ValueType() ValueType
+	MustBeValid() Any
+	ToBool() bool
+	ToInt() int
+	ToInt32() int32
+	ToInt64() int64
+	ToUint() uint
+	ToUint32() uint32
+	ToUint64() uint64
+	ToFloat32() float32
+	ToFloat64() float64
+	ToString() string
+	ToVal(val interface{})
+	Get(path ...interface{}) Any
+	Size() int
+	Keys() []string
+	GetInterface() interface{}
+	WriteTo(stream *Stream)
+}
+
+type baseAny struct{}
+
+func (any *baseAny) Get(path ...interface{}) Any {
+	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
+}
+
+func (any *baseAny) Size() int {
+	return 0
+}
+
+func (any *baseAny) Keys() []string {
+	return []string{}
+}
+
+func (any *baseAny) ToVal(obj interface{}) {
+	panic("not implemented")
+}
+
+// WrapInt32 turn int32 into Any interface
+func WrapInt32(val int32) Any {
+	return &int32Any{baseAny{}, val}
+}
+
+// WrapInt64 turn int64 into Any interface
+func WrapInt64(val int64) Any {
+	return &int64Any{baseAny{}, val}
+}
+
+// WrapUint32 turn uint32 into Any interface
+func WrapUint32(val uint32) Any {
+	return &uint32Any{baseAny{}, val}
+}
+
+// WrapUint64 turn uint64 into Any interface
+func WrapUint64(val uint64) Any {
+	return &uint64Any{baseAny{}, val}
+}
+
+// WrapFloat64 turn float64 into Any interface
+func WrapFloat64(val float64) Any {
+	return &floatAny{baseAny{}, val}
+}
+
+// WrapString turn string into Any interface
+func WrapString(val string) Any {
+	return &stringAny{baseAny{}, val}
+}
+
+// Wrap turn a go object into Any interface
+func Wrap(val interface{}) Any {
+	if val == nil {
+		return &nilAny{}
+	}
+	asAny, isAny := val.(Any)
+	if isAny {
+		return asAny
+	}
+	typ := reflect2.TypeOf(val)
+	switch typ.Kind() {
+	case reflect.Slice:
+		return wrapArray(val)
+	case reflect.Struct:
+		return wrapStruct(val)
+	case reflect.Map:
+		return wrapMap(val)
+	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)))
+	case reflect.Int16:
+		return WrapInt32(int32(val.(int16)))
+	case reflect.Int32:
+		return WrapInt32(val.(int32))
+	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:
+		return WrapUint32(uint32(val.(uint16)))
+	case reflect.Uint32:
+		return WrapUint32(uint32(val.(uint32)))
+	case reflect.Uint64:
+		return WrapUint64(val.(uint64))
+	case reflect.Float32:
+		return WrapFloat64(float64(val.(float32)))
+	case reflect.Float64:
+		return WrapFloat64(val.(float64))
+	case reflect.Bool:
+		if val.(bool) == true {
+			return &trueAny{}
+		}
+		return &falseAny{}
+	}
+	return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)}
+}
+
+// ReadAny read next JSON element as an Any object. It is a better json.RawMessage.
+func (iter *Iterator) ReadAny() Any {
+	return iter.readAny()
+}
+
+func (iter *Iterator) readAny() Any {
+	c := iter.nextToken()
+	switch c {
+	case '"':
+		iter.unreadByte()
+		return &stringAny{baseAny{}, iter.ReadString()}
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l') // null
+		return &nilAny{}
+	case 't':
+		iter.skipThreeBytes('r', 'u', 'e') // true
+		return &trueAny{}
+	case 'f':
+		iter.skipFourBytes('a', 'l', 's', 'e') // false
+		return &falseAny{}
+	case '{':
+		return iter.readObjectAny()
+	case '[':
+		return iter.readArrayAny()
+	case '-':
+		return iter.readNumberAny(false)
+	case 0:
+		return &invalidAny{baseAny{}, errors.New("input is empty")}
+	default:
+		return iter.readNumberAny(true)
+	}
+}
+
+func (iter *Iterator) readNumberAny(positive bool) Any {
+	iter.startCapture(iter.head - 1)
+	iter.skipNumber()
+	lazyBuf := iter.stopCapture()
+	return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
+}
+
+func (iter *Iterator) readObjectAny() Any {
+	iter.startCapture(iter.head - 1)
+	iter.skipObject()
+	lazyBuf := iter.stopCapture()
+	return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
+}
+
+func (iter *Iterator) readArrayAny() Any {
+	iter.startCapture(iter.head - 1)
+	iter.skipArray()
+	lazyBuf := iter.stopCapture()
+	return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
+}
+
+func locateObjectField(iter *Iterator, target string) []byte {
+	var found []byte
+	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		if field == target {
+			found = iter.SkipAndReturnBytes()
+			return false
+		}
+		iter.Skip()
+		return true
+	})
+	return found
+}
+
+func locateArrayElement(iter *Iterator, target int) []byte {
+	var found []byte
+	n := 0
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		if n == target {
+			found = iter.SkipAndReturnBytes()
+			return false
+		}
+		iter.Skip()
+		n++
+		return true
+	})
+	return found
+}
+
+func locatePath(iter *Iterator, path []interface{}) Any {
+	for i, pathKeyObj := range path {
+		switch pathKey := pathKeyObj.(type) {
+		case string:
+			valueBytes := locateObjectField(iter, pathKey)
+			if valueBytes == nil {
+				return newInvalidAny(path[i:])
+			}
+			iter.ResetBytes(valueBytes)
+		case int:
+			valueBytes := locateArrayElement(iter, pathKey)
+			if valueBytes == nil {
+				return newInvalidAny(path[i:])
+			}
+			iter.ResetBytes(valueBytes)
+		case int32:
+			if '*' == pathKey {
+				return iter.readAny().Get(path[i:]...)
+			}
+			return newInvalidAny(path[i:])
+		default:
+			return newInvalidAny(path[i:])
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		return &invalidAny{baseAny{}, iter.Error}
+	}
+	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)
+	if any == nil {
+		stream.WriteNil()
+		return
+	}
+	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/any_array.go
new file mode 100644
index 000000000..0449e9aa4
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_array.go
@@ -0,0 +1,278 @@
+package jsoniter
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type arrayLazyAny struct {
+	baseAny
+	cfg *frozenConfig
+	buf []byte
+	err error
+}
+
+func (any *arrayLazyAny) ValueType() ValueType {
+	return ArrayValue
+}
+
+func (any *arrayLazyAny) MustBeValid() Any {
+	return any
+}
+
+func (any *arrayLazyAny) LastError() error {
+	return any.err
+}
+
+func (any *arrayLazyAny) ToBool() bool {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.ReadArray()
+}
+
+func (any *arrayLazyAny) ToInt() int {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToInt32() int32 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToInt64() int64 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToUint() uint {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToUint32() uint32 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToUint64() uint64 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToFloat32() float32 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToFloat64() float64 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToString() string {
+	return *(*string)(unsafe.Pointer(&any.buf))
+}
+
+func (any *arrayLazyAny) ToVal(val interface{}) {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadVal(val)
+}
+
+func (any *arrayLazyAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case int:
+		iter := any.cfg.BorrowIterator(any.buf)
+		defer any.cfg.ReturnIterator(iter)
+		valueBytes := locateArrayElement(iter, firstPath)
+		if valueBytes == nil {
+			return newInvalidAny(path)
+		}
+		iter.ResetBytes(valueBytes)
+		return locatePath(iter, path[1:])
+	case int32:
+		if '*' == firstPath {
+			iter := any.cfg.BorrowIterator(any.buf)
+			defer any.cfg.ReturnIterator(iter)
+			arr := make([]Any, 0)
+			iter.ReadArrayCB(func(iter *Iterator) bool {
+				found := iter.readAny().Get(path[1:]...)
+				if found.ValueType() != InvalidValue {
+					arr = append(arr, found)
+				}
+				return true
+			})
+			return wrapArray(arr)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *arrayLazyAny) Size() int {
+	size := 0
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		size++
+		iter.Skip()
+		return true
+	})
+	return size
+}
+
+func (any *arrayLazyAny) WriteTo(stream *Stream) {
+	stream.Write(any.buf)
+}
+
+func (any *arrayLazyAny) GetInterface() interface{} {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.Read()
+}
+
+type arrayAny struct {
+	baseAny
+	val reflect.Value
+}
+
+func wrapArray(val interface{}) *arrayAny {
+	return &arrayAny{baseAny{}, reflect.ValueOf(val)}
+}
+
+func (any *arrayAny) ValueType() ValueType {
+	return ArrayValue
+}
+
+func (any *arrayAny) MustBeValid() Any {
+	return any
+}
+
+func (any *arrayAny) LastError() error {
+	return nil
+}
+
+func (any *arrayAny) ToBool() bool {
+	return any.val.Len() != 0
+}
+
+func (any *arrayAny) ToInt() int {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToInt32() int32 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToInt64() int64 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToUint() uint {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToUint32() uint32 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToUint64() uint64 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToFloat32() float32 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToFloat64() float64 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToString() string {
+	str, _ := MarshalToString(any.val.Interface())
+	return str
+}
+
+func (any *arrayAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case int:
+		if firstPath < 0 || firstPath >= any.val.Len() {
+			return newInvalidAny(path)
+		}
+		return Wrap(any.val.Index(firstPath).Interface())
+	case int32:
+		if '*' == firstPath {
+			mappedAll := make([]Any, 0)
+			for i := 0; i < any.val.Len(); i++ {
+				mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...)
+				if mapped.ValueType() != InvalidValue {
+					mappedAll = append(mappedAll, mapped)
+				}
+			}
+			return wrapArray(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *arrayAny) Size() int {
+	return any.val.Len()
+}
+
+func (any *arrayAny) WriteTo(stream *Stream) {
+	stream.WriteVal(any.val)
+}
+
+func (any *arrayAny) GetInterface() interface{} {
+	return any.val.Interface()
+}
diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go
new file mode 100644
index 000000000..9452324af
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_bool.go
@@ -0,0 +1,137 @@
+package jsoniter
+
+type trueAny struct {
+	baseAny
+}
+
+func (any *trueAny) LastError() error {
+	return nil
+}
+
+func (any *trueAny) ToBool() bool {
+	return true
+}
+
+func (any *trueAny) ToInt() int {
+	return 1
+}
+
+func (any *trueAny) ToInt32() int32 {
+	return 1
+}
+
+func (any *trueAny) ToInt64() int64 {
+	return 1
+}
+
+func (any *trueAny) ToUint() uint {
+	return 1
+}
+
+func (any *trueAny) ToUint32() uint32 {
+	return 1
+}
+
+func (any *trueAny) ToUint64() uint64 {
+	return 1
+}
+
+func (any *trueAny) ToFloat32() float32 {
+	return 1
+}
+
+func (any *trueAny) ToFloat64() float64 {
+	return 1
+}
+
+func (any *trueAny) ToString() string {
+	return "true"
+}
+
+func (any *trueAny) WriteTo(stream *Stream) {
+	stream.WriteTrue()
+}
+
+func (any *trueAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *trueAny) GetInterface() interface{} {
+	return true
+}
+
+func (any *trueAny) ValueType() ValueType {
+	return BoolValue
+}
+
+func (any *trueAny) MustBeValid() Any {
+	return any
+}
+
+type falseAny struct {
+	baseAny
+}
+
+func (any *falseAny) LastError() error {
+	return nil
+}
+
+func (any *falseAny) ToBool() bool {
+	return false
+}
+
+func (any *falseAny) ToInt() int {
+	return 0
+}
+
+func (any *falseAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *falseAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *falseAny) ToUint() uint {
+	return 0
+}
+
+func (any *falseAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *falseAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *falseAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *falseAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *falseAny) ToString() string {
+	return "false"
+}
+
+func (any *falseAny) WriteTo(stream *Stream) {
+	stream.WriteFalse()
+}
+
+func (any *falseAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *falseAny) GetInterface() interface{} {
+	return false
+}
+
+func (any *falseAny) ValueType() ValueType {
+	return BoolValue
+}
+
+func (any *falseAny) MustBeValid() Any {
+	return any
+}
diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/any_float.go
new file mode 100644
index 000000000..35fdb0949
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_float.go
@@ -0,0 +1,83 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type floatAny struct {
+	baseAny
+	val float64
+}
+
+func (any *floatAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *floatAny) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *floatAny) MustBeValid() Any {
+	return any
+}
+
+func (any *floatAny) LastError() error {
+	return nil
+}
+
+func (any *floatAny) ToBool() bool {
+	return any.ToFloat64() != 0
+}
+
+func (any *floatAny) ToInt() int {
+	return int(any.val)
+}
+
+func (any *floatAny) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *floatAny) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *floatAny) ToUint() uint {
+	if any.val > 0 {
+		return uint(any.val)
+	}
+	return 0
+}
+
+func (any *floatAny) ToUint32() uint32 {
+	if any.val > 0 {
+		return uint32(any.val)
+	}
+	return 0
+}
+
+func (any *floatAny) ToUint64() uint64 {
+	if any.val > 0 {
+		return uint64(any.val)
+	}
+	return 0
+}
+
+func (any *floatAny) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *floatAny) ToFloat64() float64 {
+	return any.val
+}
+
+func (any *floatAny) ToString() string {
+	return strconv.FormatFloat(any.val, 'E', -1, 64)
+}
+
+func (any *floatAny) WriteTo(stream *Stream) {
+	stream.WriteFloat64(any.val)
+}
+
+func (any *floatAny) GetInterface() interface{} {
+	return any.val
+}
diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go
new file mode 100644
index 000000000..1b56f3991
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_int32.go
@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type int32Any struct {
+	baseAny
+	val int32
+}
+
+func (any *int32Any) LastError() error {
+	return nil
+}
+
+func (any *int32Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *int32Any) MustBeValid() Any {
+	return any
+}
+
+func (any *int32Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *int32Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *int32Any) ToInt32() int32 {
+	return any.val
+}
+
+func (any *int32Any) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *int32Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *int32Any) ToUint32() uint32 {
+	return uint32(any.val)
+}
+
+func (any *int32Any) ToUint64() uint64 {
+	return uint64(any.val)
+}
+
+func (any *int32Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *int32Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *int32Any) ToString() string {
+	return strconv.FormatInt(int64(any.val), 10)
+}
+
+func (any *int32Any) WriteTo(stream *Stream) {
+	stream.WriteInt32(any.val)
+}
+
+func (any *int32Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *int32Any) GetInterface() interface{} {
+	return any.val
+}
diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go
new file mode 100644
index 000000000..c440d72b6
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_int64.go
@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type int64Any struct {
+	baseAny
+	val int64
+}
+
+func (any *int64Any) LastError() error {
+	return nil
+}
+
+func (any *int64Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *int64Any) MustBeValid() Any {
+	return any
+}
+
+func (any *int64Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *int64Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *int64Any) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *int64Any) ToInt64() int64 {
+	return any.val
+}
+
+func (any *int64Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *int64Any) ToUint32() uint32 {
+	return uint32(any.val)
+}
+
+func (any *int64Any) ToUint64() uint64 {
+	return uint64(any.val)
+}
+
+func (any *int64Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *int64Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *int64Any) ToString() string {
+	return strconv.FormatInt(any.val, 10)
+}
+
+func (any *int64Any) WriteTo(stream *Stream) {
+	stream.WriteInt64(any.val)
+}
+
+func (any *int64Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *int64Any) GetInterface() interface{} {
+	return any.val
+}
diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go
new file mode 100644
index 000000000..1d859eac3
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_invalid.go
@@ -0,0 +1,82 @@
+package jsoniter
+
+import "fmt"
+
+type invalidAny struct {
+	baseAny
+	err error
+}
+
+func newInvalidAny(path []interface{}) *invalidAny {
+	return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)}
+}
+
+func (any *invalidAny) LastError() error {
+	return any.err
+}
+
+func (any *invalidAny) ValueType() ValueType {
+	return InvalidValue
+}
+
+func (any *invalidAny) MustBeValid() Any {
+	panic(any.err)
+}
+
+func (any *invalidAny) ToBool() bool {
+	return false
+}
+
+func (any *invalidAny) ToInt() int {
+	return 0
+}
+
+func (any *invalidAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *invalidAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *invalidAny) ToUint() uint {
+	return 0
+}
+
+func (any *invalidAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *invalidAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *invalidAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *invalidAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *invalidAny) ToString() string {
+	return ""
+}
+
+func (any *invalidAny) WriteTo(stream *Stream) {
+}
+
+func (any *invalidAny) Get(path ...interface{}) Any {
+	if any.err == nil {
+		return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)}
+	}
+	return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)}
+}
+
+func (any *invalidAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *invalidAny) GetInterface() interface{} {
+	return nil
+}
diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go
new file mode 100644
index 000000000..d04cb54c1
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_nil.go
@@ -0,0 +1,69 @@
+package jsoniter
+
+type nilAny struct {
+	baseAny
+}
+
+func (any *nilAny) LastError() error {
+	return nil
+}
+
+func (any *nilAny) ValueType() ValueType {
+	return NilValue
+}
+
+func (any *nilAny) MustBeValid() Any {
+	return any
+}
+
+func (any *nilAny) ToBool() bool {
+	return false
+}
+
+func (any *nilAny) ToInt() int {
+	return 0
+}
+
+func (any *nilAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *nilAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *nilAny) ToUint() uint {
+	return 0
+}
+
+func (any *nilAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *nilAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *nilAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *nilAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *nilAny) ToString() string {
+	return ""
+}
+
+func (any *nilAny) WriteTo(stream *Stream) {
+	stream.WriteNil()
+}
+
+func (any *nilAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *nilAny) GetInterface() interface{} {
+	return nil
+}
diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/any_number.go
new file mode 100644
index 000000000..9d1e901a6
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_number.go
@@ -0,0 +1,123 @@
+package jsoniter
+
+import (
+	"io"
+	"unsafe"
+)
+
+type numberLazyAny struct {
+	baseAny
+	cfg *frozenConfig
+	buf []byte
+	err error
+}
+
+func (any *numberLazyAny) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *numberLazyAny) MustBeValid() Any {
+	return any
+}
+
+func (any *numberLazyAny) LastError() error {
+	return any.err
+}
+
+func (any *numberLazyAny) ToBool() bool {
+	return any.ToFloat64() != 0
+}
+
+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
+	}
+	return val
+}
+
+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
+	}
+	return val
+}
+
+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
+	}
+	return val
+}
+
+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
+	}
+	return val
+}
+
+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
+	}
+	return val
+}
+
+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
+	}
+	return val
+}
+
+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
+	}
+	return val
+}
+
+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
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToString() string {
+	return *(*string)(unsafe.Pointer(&any.buf))
+}
+
+func (any *numberLazyAny) WriteTo(stream *Stream) {
+	stream.Write(any.buf)
+}
+
+func (any *numberLazyAny) GetInterface() interface{} {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.Read()
+}
diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/any_object.go
new file mode 100644
index 000000000..c44ef5c98
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_object.go
@@ -0,0 +1,374 @@
+package jsoniter
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type objectLazyAny struct {
+	baseAny
+	cfg *frozenConfig
+	buf []byte
+	err error
+}
+
+func (any *objectLazyAny) ValueType() ValueType {
+	return ObjectValue
+}
+
+func (any *objectLazyAny) MustBeValid() Any {
+	return any
+}
+
+func (any *objectLazyAny) LastError() error {
+	return any.err
+}
+
+func (any *objectLazyAny) ToBool() bool {
+	return true
+}
+
+func (any *objectLazyAny) ToInt() int {
+	return 0
+}
+
+func (any *objectLazyAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *objectLazyAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *objectLazyAny) ToUint() uint {
+	return 0
+}
+
+func (any *objectLazyAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *objectLazyAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *objectLazyAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *objectLazyAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *objectLazyAny) ToString() string {
+	return *(*string)(unsafe.Pointer(&any.buf))
+}
+
+func (any *objectLazyAny) ToVal(obj interface{}) {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadVal(obj)
+}
+
+func (any *objectLazyAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case string:
+		iter := any.cfg.BorrowIterator(any.buf)
+		defer any.cfg.ReturnIterator(iter)
+		valueBytes := locateObjectField(iter, firstPath)
+		if valueBytes == nil {
+			return newInvalidAny(path)
+		}
+		iter.ResetBytes(valueBytes)
+		return locatePath(iter, path[1:])
+	case int32:
+		if '*' == firstPath {
+			mappedAll := map[string]Any{}
+			iter := any.cfg.BorrowIterator(any.buf)
+			defer any.cfg.ReturnIterator(iter)
+			iter.ReadMapCB(func(iter *Iterator, field string) bool {
+				mapped := locatePath(iter, path[1:])
+				if mapped.ValueType() != InvalidValue {
+					mappedAll[field] = mapped
+				}
+				return true
+			})
+			return wrapMap(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *objectLazyAny) Keys() []string {
+	keys := []string{}
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadMapCB(func(iter *Iterator, field string) bool {
+		iter.Skip()
+		keys = append(keys, field)
+		return true
+	})
+	return keys
+}
+
+func (any *objectLazyAny) Size() int {
+	size := 0
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		iter.Skip()
+		size++
+		return true
+	})
+	return size
+}
+
+func (any *objectLazyAny) WriteTo(stream *Stream) {
+	stream.Write(any.buf)
+}
+
+func (any *objectLazyAny) GetInterface() interface{} {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.Read()
+}
+
+type objectAny struct {
+	baseAny
+	err error
+	val reflect.Value
+}
+
+func wrapStruct(val interface{}) *objectAny {
+	return &objectAny{baseAny{}, nil, reflect.ValueOf(val)}
+}
+
+func (any *objectAny) ValueType() ValueType {
+	return ObjectValue
+}
+
+func (any *objectAny) MustBeValid() Any {
+	return any
+}
+
+func (any *objectAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *objectAny) LastError() error {
+	return any.err
+}
+
+func (any *objectAny) ToBool() bool {
+	return any.val.NumField() != 0
+}
+
+func (any *objectAny) ToInt() int {
+	return 0
+}
+
+func (any *objectAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *objectAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *objectAny) ToUint() uint {
+	return 0
+}
+
+func (any *objectAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *objectAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *objectAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *objectAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *objectAny) ToString() string {
+	str, err := MarshalToString(any.val.Interface())
+	any.err = err
+	return str
+}
+
+func (any *objectAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case string:
+		field := any.val.FieldByName(firstPath)
+		if !field.IsValid() {
+			return newInvalidAny(path)
+		}
+		return Wrap(field.Interface())
+	case int32:
+		if '*' == firstPath {
+			mappedAll := map[string]Any{}
+			for i := 0; i < any.val.NumField(); i++ {
+				field := any.val.Field(i)
+				if field.CanInterface() {
+					mapped := Wrap(field.Interface()).Get(path[1:]...)
+					if mapped.ValueType() != InvalidValue {
+						mappedAll[any.val.Type().Field(i).Name] = mapped
+					}
+				}
+			}
+			return wrapMap(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *objectAny) Keys() []string {
+	keys := make([]string, 0, any.val.NumField())
+	for i := 0; i < any.val.NumField(); i++ {
+		keys = append(keys, any.val.Type().Field(i).Name)
+	}
+	return keys
+}
+
+func (any *objectAny) Size() int {
+	return any.val.NumField()
+}
+
+func (any *objectAny) WriteTo(stream *Stream) {
+	stream.WriteVal(any.val)
+}
+
+func (any *objectAny) GetInterface() interface{} {
+	return any.val.Interface()
+}
+
+type mapAny struct {
+	baseAny
+	err error
+	val reflect.Value
+}
+
+func wrapMap(val interface{}) *mapAny {
+	return &mapAny{baseAny{}, nil, reflect.ValueOf(val)}
+}
+
+func (any *mapAny) ValueType() ValueType {
+	return ObjectValue
+}
+
+func (any *mapAny) MustBeValid() Any {
+	return any
+}
+
+func (any *mapAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *mapAny) LastError() error {
+	return any.err
+}
+
+func (any *mapAny) ToBool() bool {
+	return true
+}
+
+func (any *mapAny) ToInt() int {
+	return 0
+}
+
+func (any *mapAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *mapAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *mapAny) ToUint() uint {
+	return 0
+}
+
+func (any *mapAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *mapAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *mapAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *mapAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *mapAny) ToString() string {
+	str, err := MarshalToString(any.val.Interface())
+	any.err = err
+	return str
+}
+
+func (any *mapAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case int32:
+		if '*' == firstPath {
+			mappedAll := map[string]Any{}
+			for _, key := range any.val.MapKeys() {
+				keyAsStr := key.String()
+				element := Wrap(any.val.MapIndex(key).Interface())
+				mapped := element.Get(path[1:]...)
+				if mapped.ValueType() != InvalidValue {
+					mappedAll[keyAsStr] = mapped
+				}
+			}
+			return wrapMap(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		value := any.val.MapIndex(reflect.ValueOf(firstPath))
+		if !value.IsValid() {
+			return newInvalidAny(path)
+		}
+		return Wrap(value.Interface())
+	}
+}
+
+func (any *mapAny) Keys() []string {
+	keys := make([]string, 0, any.val.Len())
+	for _, key := range any.val.MapKeys() {
+		keys = append(keys, key.String())
+	}
+	return keys
+}
+
+func (any *mapAny) Size() int {
+	return any.val.Len()
+}
+
+func (any *mapAny) WriteTo(stream *Stream) {
+	stream.WriteVal(any.val)
+}
+
+func (any *mapAny) GetInterface() interface{} {
+	return any.val.Interface()
+}
diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/any_str.go
new file mode 100644
index 000000000..a4b93c78c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_str.go
@@ -0,0 +1,166 @@
+package jsoniter
+
+import (
+	"fmt"
+	"strconv"
+)
+
+type stringAny struct {
+	baseAny
+	val string
+}
+
+func (any *stringAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
+}
+
+func (any *stringAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *stringAny) ValueType() ValueType {
+	return StringValue
+}
+
+func (any *stringAny) MustBeValid() Any {
+	return any
+}
+
+func (any *stringAny) LastError() error {
+	return nil
+}
+
+func (any *stringAny) ToBool() bool {
+	str := any.ToString()
+	if str == "0" {
+		return false
+	}
+	for _, c := range str {
+		switch c {
+		case ' ', '\n', '\r', '\t':
+		default:
+			return true
+		}
+	}
+	return false
+}
+
+func (any *stringAny) ToInt() int {
+	return int(any.ToInt64())
+
+}
+
+func (any *stringAny) ToInt32() int32 {
+	return int32(any.ToInt64())
+}
+
+func (any *stringAny) ToInt64() int64 {
+	if any.val == "" {
+		return 0
+	}
+
+	flag := 1
+	startPos := 0
+	endPos := 0
+	if any.val[0] == '+' || any.val[0] == '-' {
+		startPos = 1
+	}
+
+	if any.val[0] == '-' {
+		flag = -1
+	}
+
+	for i := startPos; i < len(any.val); i++ {
+		if any.val[i] >= '0' && any.val[i] <= '9' {
+			endPos = i + 1
+		} else {
+			break
+		}
+	}
+	parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64)
+	return int64(flag) * parsed
+}
+
+func (any *stringAny) ToUint() uint {
+	return uint(any.ToUint64())
+}
+
+func (any *stringAny) ToUint32() uint32 {
+	return uint32(any.ToUint64())
+}
+
+func (any *stringAny) ToUint64() uint64 {
+	if any.val == "" {
+		return 0
+	}
+
+	startPos := 0
+	endPos := 0
+
+	if any.val[0] == '-' {
+		return 0
+	}
+	if any.val[0] == '+' {
+		startPos = 1
+	}
+
+	for i := startPos; i < len(any.val); i++ {
+		if any.val[i] >= '0' && any.val[i] <= '9' {
+			endPos = i + 1
+		} else {
+			break
+		}
+	}
+	parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64)
+	return parsed
+}
+
+func (any *stringAny) ToFloat32() float32 {
+	return float32(any.ToFloat64())
+}
+
+func (any *stringAny) ToFloat64() float64 {
+	if len(any.val) == 0 {
+		return 0
+	}
+
+	// first char invalid
+	if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') {
+		return 0
+	}
+
+	// extract valid num expression from string
+	// eg 123true => 123, -12.12xxa => -12.12
+	endPos := 1
+	for i := 1; i < len(any.val); i++ {
+		if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' {
+			endPos = i + 1
+			continue
+		}
+
+		// end position is the first char which is not digit
+		if any.val[i] >= '0' && any.val[i] <= '9' {
+			endPos = i + 1
+		} else {
+			endPos = i
+			break
+		}
+	}
+	parsed, _ := strconv.ParseFloat(any.val[:endPos], 64)
+	return parsed
+}
+
+func (any *stringAny) ToString() string {
+	return any.val
+}
+
+func (any *stringAny) WriteTo(stream *Stream) {
+	stream.WriteString(any.val)
+}
+
+func (any *stringAny) GetInterface() interface{} {
+	return any.val
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_array_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_array_test.go
new file mode 100644
index 000000000..a28bd8d38
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_array_test.go
@@ -0,0 +1,123 @@
+package any_tests
+
+import (
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_read_empty_array_as_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("[]"))
+	should.Equal(jsoniter.ArrayValue, any.Get().ValueType())
+	should.Equal(jsoniter.InvalidValue, any.Get(0.3).ValueType())
+	should.Equal(0, any.Size())
+	should.Equal(jsoniter.ArrayValue, any.ValueType())
+	should.Nil(any.LastError())
+	should.Equal(0, any.ToInt())
+	should.Equal(int32(0), any.ToInt32())
+	should.Equal(int64(0), any.ToInt64())
+	should.Equal(uint(0), any.ToUint())
+	should.Equal(uint32(0), any.ToUint32())
+	should.Equal(uint64(0), any.ToUint64())
+	should.Equal(float32(0), any.ToFloat32())
+	should.Equal(float64(0), any.ToFloat64())
+}
+
+func Test_read_one_element_array_as_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("[1]"))
+	should.Equal(1, any.Size())
+}
+
+func Test_read_two_element_array_as_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("[1,2]"))
+	should.Equal(1, any.Get(0).ToInt())
+	should.Equal(2, any.Size())
+	should.True(any.ToBool())
+	should.Equal(1, any.ToInt())
+	should.Equal([]interface{}{float64(1), float64(2)}, any.GetInterface())
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("[1,2]", string(stream.Buffer()))
+	arr := []int{}
+	any.ToVal(&arr)
+	should.Equal([]int{1, 2}, arr)
+}
+
+func Test_wrap_array_and_convert_to_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Wrap([]int{1, 2, 3})
+	any2 := jsoniter.Wrap([]int{})
+
+	should.Equal("[1,2,3]", any.ToString())
+	should.True(any.ToBool())
+	should.False(any2.ToBool())
+
+	should.Equal(1, any.ToInt())
+	should.Equal(0, any2.ToInt())
+	should.Equal(int32(1), any.ToInt32())
+	should.Equal(int32(0), any2.ToInt32())
+	should.Equal(int64(1), any.ToInt64())
+	should.Equal(int64(0), any2.ToInt64())
+	should.Equal(uint(1), any.ToUint())
+	should.Equal(uint(0), any2.ToUint())
+	should.Equal(uint32(1), any.ToUint32())
+	should.Equal(uint32(0), any2.ToUint32())
+	should.Equal(uint64(1), any.ToUint64())
+	should.Equal(uint64(0), any2.ToUint64())
+	should.Equal(float32(1), any.ToFloat32())
+	should.Equal(float32(0), any2.ToFloat32())
+	should.Equal(float64(1), any.ToFloat64())
+	should.Equal(float64(0), any2.ToFloat64())
+	should.Equal(3, any.Size())
+	should.Equal(0, any2.Size())
+
+	var i interface{} = []int{1, 2, 3}
+	should.Equal(i, any.GetInterface())
+}
+
+func Test_array_lazy_any_get(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("[1,[2,3],4]"))
+	should.Equal(3, any.Get(1, 1).ToInt())
+	should.Equal("[1,[2,3],4]", any.ToString())
+}
+
+func Test_array_lazy_any_get_all(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("[[1],[2],[3,4]]"))
+	should.Equal("[1,2,3]", any.Get('*', 0).ToString())
+	any = jsoniter.Get([]byte("[[[1],[2],[3,4]]]"), 0, '*', 0)
+	should.Equal("[1,2,3]", any.ToString())
+}
+
+func Test_array_wrapper_any_get_all(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Wrap([][]int{
+		{1, 2},
+		{3, 4},
+		{5, 6},
+	})
+	should.Equal("[1,3,5]", any.Get('*', 0).ToString())
+	should.Equal(jsoniter.ArrayValue, any.ValueType())
+	should.True(any.ToBool())
+	should.Equal(1, any.Get(0, 0).ToInt())
+}
+
+func Test_array_lazy_any_get_invalid(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("[]"))
+	should.Equal(jsoniter.InvalidValue, any.Get(1, 1).ValueType())
+	should.NotNil(any.Get(1, 1).LastError())
+	should.Equal(jsoniter.InvalidValue, any.Get("1").ValueType())
+	should.NotNil(any.Get("1").LastError())
+}
+
+func Test_invalid_array(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("["), 0)
+	should.Equal(jsoniter.InvalidValue, any.ValueType())
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_bool_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_bool_test.go
new file mode 100644
index 000000000..045671f28
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_bool_test.go
@@ -0,0 +1,65 @@
+package any_tests
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+var boolConvertMap = map[string]bool{
+	"null":  false,
+	"true":  true,
+	"false": false,
+
+	`"true"`:  true,
+	`"false"`: true,
+
+	"123":   true,
+	`"123"`: true,
+	"0":     false,
+	`"0"`:   false,
+	"-1":    true,
+	`"-1"`:  true,
+
+	"1.1":       true,
+	"0.0":       false,
+	"-1.1":      true,
+	`""`:        false,
+	"[1,2]":     true,
+	"[]":        false,
+	"{}":        true,
+	`{"abc":1}`: true,
+}
+
+func Test_read_bool_as_any(t *testing.T) {
+	should := require.New(t)
+
+	var any jsoniter.Any
+	for k, v := range boolConvertMap {
+		any = jsoniter.Get([]byte(k))
+		if v {
+			should.True(any.ToBool(), fmt.Sprintf("origin val is %v", k))
+		} else {
+			should.False(any.ToBool(), fmt.Sprintf("origin val is %v", k))
+		}
+	}
+
+}
+
+func Test_write_bool_to_stream(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("true"))
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("true", string(stream.Buffer()))
+	should.Equal(any.ValueType(), jsoniter.BoolValue)
+
+	any = jsoniter.Get([]byte("false"))
+	stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("false", string(stream.Buffer()))
+
+	should.Equal(any.ValueType(), jsoniter.BoolValue)
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_float_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_float_test.go
new file mode 100644
index 000000000..5e70598a1
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_float_test.go
@@ -0,0 +1,101 @@
+package any_tests
+
+import (
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+var floatConvertMap = map[string]float64{
+	"null":  0,
+	"true":  1,
+	"false": 0,
+
+	`"true"`:  0,
+	`"false"`: 0,
+
+	"1e1":  10,
+	"1e+1": 10,
+	"1e-1": .1,
+	"1E1":  10,
+	"1E+1": 10,
+	"1E-1": .1,
+
+	"-1e1":  -10,
+	"-1e+1": -10,
+	"-1e-1": -.1,
+	"-1E1":  -10,
+	"-1E+1": -10,
+	"-1E-1": -.1,
+
+	`"1e1"`:  10,
+	`"1e+1"`: 10,
+	`"1e-1"`: .1,
+	`"1E1"`:  10,
+	`"1E+1"`: 10,
+	`"1E-1"`: .1,
+
+	`"-1e1"`:  -10,
+	`"-1e+1"`: -10,
+	`"-1e-1"`: -.1,
+	`"-1E1"`:  -10,
+	`"-1E+1"`: -10,
+	`"-1E-1"`: -.1,
+
+	"123":       123,
+	`"123true"`: 123,
+	`"+"`:       0,
+	`"-"`:       0,
+
+	`"-123true"`:  -123,
+	`"-99.9true"`: -99.9,
+	"0":           0,
+	`"0"`:         0,
+	"-1":          -1,
+
+	"1.1":       1.1,
+	"0.0":       0,
+	"-1.1":      -1.1,
+	`"+1.1"`:    1.1,
+	`""`:        0,
+	"[1,2]":     1,
+	"[]":        0,
+	"{}":        0,
+	`{"abc":1}`: 0,
+}
+
+func Test_read_any_to_float(t *testing.T) {
+	should := require.New(t)
+	for k, v := range floatConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(float64(v), any.ToFloat64(), "the original val is "+k)
+	}
+
+	for k, v := range floatConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(float32(v), any.ToFloat32(), "the original val is "+k)
+	}
+}
+
+func Test_read_float_to_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.WrapFloat64(12.3)
+	anyFloat64 := float64(12.3)
+	any2 := jsoniter.WrapFloat64(-1.1)
+	should.Equal(float64(12.3), any.ToFloat64())
+	should.True(any.ToBool())
+	should.Equal(float32(anyFloat64), any.ToFloat32())
+	should.Equal(int(anyFloat64), any.ToInt())
+	should.Equal(int32(anyFloat64), any.ToInt32())
+	should.Equal(int64(anyFloat64), any.ToInt64())
+	should.Equal(uint(anyFloat64), any.ToUint())
+	should.Equal(uint32(anyFloat64), any.ToUint32())
+	should.Equal(uint64(anyFloat64), any.ToUint64())
+	should.Equal(uint(0), any2.ToUint())
+	should.Equal(uint32(0), any2.ToUint32())
+	should.Equal(uint64(0), any2.ToUint64())
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+
+	should.Equal("1.23E+01", any.ToString())
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_int_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_int_test.go
new file mode 100644
index 000000000..c5a3d4260
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_int_test.go
@@ -0,0 +1,198 @@
+package any_tests
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+var intConvertMap = map[string]int{
+	"null":       0,
+	"321.1":      321,
+	"-321.1":     -321,
+	`"1.1"`:      1,
+	`"-321.1"`:   -321,
+	"0.0":        0,
+	"0":          0,
+	`"0"`:        0,
+	`"0.0"`:      0,
+	"-1.1":       -1,
+	"true":       1,
+	"false":      0,
+	`"true"`:     0,
+	`"false"`:    0,
+	`"true123"`:  0,
+	`"123true"`:  123,
+	`"-123true"`: -123,
+	`"1.2332e6"`: 1,
+	`""`:         0,
+	"+":          0,
+	"-":          0,
+	"[]":         0,
+	"[1,2]":      1,
+	`["1","2"]`:  1,
+	// object in php cannot convert to int
+	"{}": 0,
+}
+
+func Test_read_any_to_int(t *testing.T) {
+	should := require.New(t)
+
+	// int
+	for k, v := range intConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(v, any.ToInt(), fmt.Sprintf("origin val %v", k))
+	}
+
+	// int32
+	for k, v := range intConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(int32(v), any.ToInt32(), fmt.Sprintf("original val is %v", k))
+	}
+
+	// int64
+	for k, v := range intConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(int64(v), any.ToInt64(), fmt.Sprintf("original val is %v", k))
+	}
+
+}
+
+var uintConvertMap = map[string]int{
+	"null":       0,
+	"321.1":      321,
+	`"1.1"`:      1,
+	`"-123.1"`:   0,
+	"0.0":        0,
+	"0":          0,
+	`"0"`:        0,
+	`"0.0"`:      0,
+	`"00.0"`:     0,
+	"true":       1,
+	"false":      0,
+	`"true"`:     0,
+	`"false"`:    0,
+	`"true123"`:  0,
+	`"+1"`:       1,
+	`"123true"`:  123,
+	`"-123true"`: 0,
+	`"1.2332e6"`: 1,
+	`""`:         0,
+	"+":          0,
+	"-":          0,
+	".":          0,
+	"[]":         0,
+	"[1,2]":      1,
+	"{}":         0,
+	"{1,2}":      0,
+	"-1.1":       0,
+	"-321.1":     0,
+}
+
+func Test_read_any_to_uint(t *testing.T) {
+	should := require.New(t)
+
+	for k, v := range uintConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(uint64(v), any.ToUint64(), fmt.Sprintf("origin val %v", k))
+	}
+
+	for k, v := range uintConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k))
+	}
+
+	for k, v := range uintConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(uint(v), any.ToUint(), fmt.Sprintf("origin val %v", k))
+	}
+
+}
+
+func Test_read_int64_to_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.WrapInt64(12345)
+	should.Equal(12345, any.ToInt())
+	should.Equal(int32(12345), any.ToInt32())
+	should.Equal(int64(12345), any.ToInt64())
+	should.Equal(uint(12345), any.ToUint())
+	should.Equal(uint32(12345), any.ToUint32())
+	should.Equal(uint64(12345), any.ToUint64())
+	should.Equal(float32(12345), any.ToFloat32())
+	should.Equal(float64(12345), any.ToFloat64())
+	should.Equal("12345", any.ToString())
+	should.Equal(true, any.ToBool())
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("12345", string(stream.Buffer()))
+}
+func Test_read_int32_to_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.WrapInt32(12345)
+	should.Equal(12345, any.ToInt())
+	should.Equal(int32(12345), any.ToInt32())
+	should.Equal(int64(12345), any.ToInt64())
+	should.Equal(uint(12345), any.ToUint())
+	should.Equal(uint32(12345), any.ToUint32())
+	should.Equal(uint64(12345), any.ToUint64())
+	should.Equal(float32(12345), any.ToFloat32())
+	should.Equal(float64(12345), any.ToFloat64())
+	should.Equal("12345", any.ToString())
+	should.Equal(true, any.ToBool())
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("12345", string(stream.Buffer()))
+}
+
+func Test_read_uint32_to_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.WrapUint32(12345)
+	should.Equal(12345, any.ToInt())
+	should.Equal(int32(12345), any.ToInt32())
+	should.Equal(int64(12345), any.ToInt64())
+	should.Equal(uint(12345), any.ToUint())
+	should.Equal(uint32(12345), any.ToUint32())
+	should.Equal(uint64(12345), any.ToUint64())
+	should.Equal(float32(12345), any.ToFloat32())
+	should.Equal(float64(12345), any.ToFloat64())
+	should.Equal("12345", any.ToString())
+	should.Equal(true, any.ToBool())
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("12345", string(stream.Buffer()))
+}
+
+func Test_read_uint64_to_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.WrapUint64(12345)
+	should.Equal(12345, any.ToInt())
+	should.Equal(int32(12345), any.ToInt32())
+	should.Equal(int64(12345), any.ToInt64())
+	should.Equal(uint(12345), any.ToUint())
+	should.Equal(uint32(12345), any.ToUint32())
+	should.Equal(uint64(12345), any.ToUint64())
+	should.Equal(float32(12345), any.ToFloat32())
+	should.Equal(float64(12345), any.ToFloat64())
+	should.Equal("12345", any.ToString())
+	should.Equal(true, any.ToBool())
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("12345", string(stream.Buffer()))
+	stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	stream.WriteUint(uint(123))
+	should.Equal("123", string(stream.Buffer()))
+}
+
+func Test_int_lazy_any_get(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("1234"))
+	// panic!!
+	//should.Equal(any.LastError(), io.EOF)
+	should.Equal(jsoniter.InvalidValue, any.Get(1, "2").ValueType())
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_map_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_map_test.go
new file mode 100644
index 000000000..c5f2e6fea
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_map_test.go
@@ -0,0 +1,28 @@
+package any_tests
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func Test_wrap_map(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Wrap(map[string]string{"Field1": "hello"})
+	should.Equal("hello", any.Get("Field1").ToString())
+	any = jsoniter.Wrap(map[string]string{"Field1": "hello"})
+	should.Equal(1, any.Size())
+}
+
+func Test_map_wrapper_any_get_all(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Wrap(map[string][]int{"Field1": {1, 2}})
+	should.Equal(`{"Field1":1}`, any.Get('*', 0).ToString())
+	should.Contains(any.Keys(), "Field1")
+
+	// map write to
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
+	any.WriteTo(stream)
+	// TODO cannot pass
+	//should.Equal(string(stream.buf), "")
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_null_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_null_test.go
new file mode 100644
index 000000000..a86625e9a
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_null_test.go
@@ -0,0 +1,16 @@
+package any_tests
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func Test_read_null_as_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte(`null`))
+	should.Equal(0, any.ToInt())
+	should.Equal(float64(0), any.ToFloat64())
+	should.Equal("", any.ToString())
+	should.False(any.ToBool())
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_object_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_object_test.go
new file mode 100644
index 000000000..5af292da6
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_object_test.go
@@ -0,0 +1,121 @@
+package any_tests
+
+import (
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_read_object_as_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte(`{"a":"stream","c":"d"}`))
+	should.Equal(`{"a":"stream","c":"d"}`, any.ToString())
+	// partial parse
+	should.Equal("stream", any.Get("a").ToString())
+	should.Equal("d", any.Get("c").ToString())
+	should.Equal(2, len(any.Keys()))
+	any = jsoniter.Get([]byte(`{"a":"stream","c":"d"}`))
+	// full parse
+	should.Equal(2, len(any.Keys()))
+	should.Equal(2, any.Size())
+	should.True(any.ToBool())
+	should.Equal(0, any.ToInt())
+	should.Equal(jsoniter.ObjectValue, any.ValueType())
+	should.Nil(any.LastError())
+	obj := struct {
+		A string
+	}{}
+	any.ToVal(&obj)
+	should.Equal("stream", obj.A)
+}
+
+func Test_object_lazy_any_get(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte(`{"a":{"stream":{"c":"d"}}}`))
+	should.Equal("d", any.Get("a", "stream", "c").ToString())
+}
+
+func Test_object_lazy_any_get_all(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte(`{"a":[0],"stream":[1]}`))
+	should.Contains(any.Get('*', 0).ToString(), `"a":0`)
+}
+
+func Test_object_lazy_any_get_invalid(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte(`{}`))
+	should.Equal(jsoniter.InvalidValue, any.Get("a", "stream", "c").ValueType())
+	should.Equal(jsoniter.InvalidValue, any.Get(1).ValueType())
+}
+
+func Test_wrap_map_and_convert_to_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Wrap(map[string]interface{}{"a": 1})
+	should.True(any.ToBool())
+	should.Equal(0, any.ToInt())
+	should.Equal(int32(0), any.ToInt32())
+	should.Equal(int64(0), any.ToInt64())
+	should.Equal(float32(0), any.ToFloat32())
+	should.Equal(float64(0), any.ToFloat64())
+	should.Equal(uint(0), any.ToUint())
+	should.Equal(uint32(0), any.ToUint32())
+	should.Equal(uint64(0), any.ToUint64())
+}
+
+func Test_wrap_object_and_convert_to_any(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		field2 string
+	}
+	any := jsoniter.Wrap(TestObject{"hello", "world"})
+	should.Equal("hello", any.Get("Field1").ToString())
+	any = jsoniter.Wrap(TestObject{"hello", "world"})
+	should.Equal(2, any.Size())
+	should.Equal(`{"Field1":"hello"}`, any.Get('*').ToString())
+
+	should.Equal(0, any.ToInt())
+	should.Equal(int32(0), any.ToInt32())
+	should.Equal(int64(0), any.ToInt64())
+	should.Equal(float32(0), any.ToFloat32())
+	should.Equal(float64(0), any.ToFloat64())
+	should.Equal(uint(0), any.ToUint())
+	should.Equal(uint32(0), any.ToUint32())
+	should.Equal(uint64(0), any.ToUint64())
+	should.True(any.ToBool())
+	should.Equal(`{"Field1":"hello"}`, any.ToString())
+
+	// cannot pass!
+	//stream := NewStream(ConfigDefault, nil, 32)
+	//any.WriteTo(stream)
+	//should.Equal(`{"Field1":"hello"}`, string(stream.Buffer()))
+	// cannot pass!
+
+}
+
+func Test_any_within_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 jsoniter.Any
+		Field2 jsoniter.Any
+	}
+	obj := TestObject{}
+	err := jsoniter.UnmarshalFromString(`{"Field1": "hello", "Field2": [1,2,3]}`, &obj)
+	should.Nil(err)
+	should.Equal("hello", obj.Field1.ToString())
+	should.Equal("[1,2,3]", obj.Field2.ToString())
+}
+
+func Test_object_wrapper_any_get_all(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 []int
+		Field2 []int
+	}
+	any := jsoniter.Wrap(TestObject{[]int{1, 2}, []int{3, 4}})
+	should.Contains(any.Get('*', 0).ToString(), `"Field2":3`)
+	should.Contains(any.Keys(), "Field1")
+	should.Contains(any.Keys(), "Field2")
+	should.NotContains(any.Keys(), "Field3")
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_string_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_string_test.go
new file mode 100644
index 000000000..bd24db47f
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_any_string_test.go
@@ -0,0 +1,58 @@
+package any_tests
+
+import (
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+var stringConvertMap = map[string]string{
+	"null":                   "",
+	"321.1":                  "321.1",
+	`"1.1"`:                  "1.1",
+	`"-123.1"`:               "-123.1",
+	"0.0":                    "0.0",
+	"0":                      "0",
+	`"0"`:                    "0",
+	`"0.0"`:                  "0.0",
+	`"00.0"`:                 "00.0",
+	"true":                   "true",
+	"false":                  "false",
+	`"true"`:                 "true",
+	`"false"`:                "false",
+	`"true123"`:              "true123",
+	`"+1"`:                   "+1",
+	"[]":                     "[]",
+	"[1,2]":                  "[1,2]",
+	"{}":                     "{}",
+	`{"a":1, "stream":true}`: `{"a":1, "stream":true}`,
+}
+
+func Test_read_any_to_string(t *testing.T) {
+	should := require.New(t)
+	for k, v := range stringConvertMap {
+		any := jsoniter.Get([]byte(k))
+		should.Equal(v, any.ToString(), "original val "+k)
+	}
+}
+
+func Test_read_string_as_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte(`"hello"`))
+	should.Equal("hello", any.ToString())
+	should.True(any.ToBool())
+	any = jsoniter.Get([]byte(`" "`))
+	should.False(any.ToBool())
+	any = jsoniter.Get([]byte(`"false"`))
+	should.True(any.ToBool())
+	any = jsoniter.Get([]byte(`"123"`))
+	should.Equal(123, any.ToInt())
+}
+
+func Test_wrap_string(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("-32000")).MustBeValid()
+	should.Equal(-32000, any.ToInt())
+	should.NoError(any.LastError())
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_must_be_valid_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_must_be_valid_test.go
new file mode 100644
index 000000000..8974eb7f7
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_must_be_valid_test.go
@@ -0,0 +1,72 @@
+package any_tests
+
+import (
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+// if must be valid is useless, just drop this test
+func Test_must_be_valid(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("123"))
+	should.Equal(any.MustBeValid().ToInt(), 123)
+
+	any = jsoniter.Wrap(int8(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(int16(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(int32(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(int64(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(uint(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(uint8(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(uint16(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(uint32(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(uint64(10))
+	should.Equal(any.MustBeValid().ToInt(), 10)
+
+	any = jsoniter.Wrap(float32(10))
+	should.Equal(any.MustBeValid().ToFloat64(), float64(10))
+
+	any = jsoniter.Wrap(float64(10))
+	should.Equal(any.MustBeValid().ToFloat64(), float64(10))
+
+	any = jsoniter.Wrap(true)
+	should.Equal(any.MustBeValid().ToFloat64(), float64(1))
+
+	any = jsoniter.Wrap(false)
+	should.Equal(any.MustBeValid().ToFloat64(), float64(0))
+
+	any = jsoniter.Wrap(nil)
+	should.Equal(any.MustBeValid().ToFloat64(), float64(0))
+
+	any = jsoniter.Wrap(struct{ age int }{age: 1})
+	should.Equal(any.MustBeValid().ToFloat64(), float64(0))
+
+	any = jsoniter.Wrap(map[string]interface{}{"abc": 1})
+	should.Equal(any.MustBeValid().ToFloat64(), float64(0))
+
+	any = jsoniter.Wrap("abc")
+	should.Equal(any.MustBeValid().ToFloat64(), float64(0))
+
+	any = jsoniter.Wrap([]int{})
+	should.Equal(any.MustBeValid().ToFloat64(), float64(0))
+
+	any = jsoniter.Wrap([]int{1, 2})
+	should.Equal(any.MustBeValid().ToFloat64(), float64(1))
+}
diff --git a/vendor/github.com/json-iterator/go/any_tests/jsoniter_wrap_test.go b/vendor/github.com/json-iterator/go/any_tests/jsoniter_wrap_test.go
new file mode 100644
index 000000000..480985ffa
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_tests/jsoniter_wrap_test.go
@@ -0,0 +1,119 @@
+package any_tests
+
+import (
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_wrap_and_valuetype_everything(t *testing.T) {
+	should := require.New(t)
+	var i interface{}
+	any := jsoniter.Get([]byte("123"))
+	// default of number type is float64
+	i = float64(123)
+	should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(int8(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	//  get interface is not int8 interface
+	// i = int8(10)
+	// should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(int16(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	//i = int16(10)
+	//should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(int32(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	i = int32(10)
+	should.Equal(i, any.GetInterface())
+	any = jsoniter.Wrap(int64(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	i = int64(10)
+	should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(uint(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	// not equal
+	//i = uint(10)
+	//should.Equal(i, any.GetInterface())
+	any = jsoniter.Wrap(uint8(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	// not equal
+	// i = uint8(10)
+	// should.Equal(i, any.GetInterface())
+	any = jsoniter.Wrap(uint16(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	any = jsoniter.Wrap(uint32(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	i = uint32(10)
+	should.Equal(i, any.GetInterface())
+	any = jsoniter.Wrap(uint64(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	i = uint64(10)
+	should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(float32(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	// not equal
+	//i = float32(10)
+	//should.Equal(i, any.GetInterface())
+	any = jsoniter.Wrap(float64(10))
+	should.Equal(any.ValueType(), jsoniter.NumberValue)
+	should.Equal(any.LastError(), nil)
+	i = float64(10)
+	should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(true)
+	should.Equal(any.ValueType(), jsoniter.BoolValue)
+	should.Equal(any.LastError(), nil)
+	i = true
+	should.Equal(i, any.GetInterface())
+	any = jsoniter.Wrap(false)
+	should.Equal(any.ValueType(), jsoniter.BoolValue)
+	should.Equal(any.LastError(), nil)
+	i = false
+	should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(nil)
+	should.Equal(any.ValueType(), jsoniter.NilValue)
+	should.Equal(any.LastError(), nil)
+	i = nil
+	should.Equal(i, any.GetInterface())
+
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32)
+	any.WriteTo(stream)
+	should.Equal("null", string(stream.Buffer()))
+	should.Equal(any.LastError(), nil)
+
+	any = jsoniter.Wrap(struct{ age int }{age: 1})
+	should.Equal(any.ValueType(), jsoniter.ObjectValue)
+	should.Equal(any.LastError(), nil)
+	i = struct{ age int }{age: 1}
+	should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap(map[string]interface{}{"abc": 1})
+	should.Equal(any.ValueType(), jsoniter.ObjectValue)
+	should.Equal(any.LastError(), nil)
+	i = map[string]interface{}{"abc": 1}
+	should.Equal(i, any.GetInterface())
+
+	any = jsoniter.Wrap("abc")
+	i = "abc"
+	should.Equal(i, any.GetInterface())
+	should.Equal(nil, any.LastError())
+
+}
diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go
new file mode 100644
index 000000000..656bbd33d
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_uint32.go
@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type uint32Any struct {
+	baseAny
+	val uint32
+}
+
+func (any *uint32Any) LastError() error {
+	return nil
+}
+
+func (any *uint32Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *uint32Any) MustBeValid() Any {
+	return any
+}
+
+func (any *uint32Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *uint32Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *uint32Any) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *uint32Any) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *uint32Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *uint32Any) ToUint32() uint32 {
+	return any.val
+}
+
+func (any *uint32Any) ToUint64() uint64 {
+	return uint64(any.val)
+}
+
+func (any *uint32Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *uint32Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *uint32Any) ToString() string {
+	return strconv.FormatInt(int64(any.val), 10)
+}
+
+func (any *uint32Any) WriteTo(stream *Stream) {
+	stream.WriteUint32(any.val)
+}
+
+func (any *uint32Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *uint32Any) GetInterface() interface{} {
+	return any.val
+}
diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go
new file mode 100644
index 000000000..7df2fce33
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/any_uint64.go
@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type uint64Any struct {
+	baseAny
+	val uint64
+}
+
+func (any *uint64Any) LastError() error {
+	return nil
+}
+
+func (any *uint64Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *uint64Any) MustBeValid() Any {
+	return any
+}
+
+func (any *uint64Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *uint64Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *uint64Any) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *uint64Any) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *uint64Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *uint64Any) ToUint32() uint32 {
+	return uint32(any.val)
+}
+
+func (any *uint64Any) ToUint64() uint64 {
+	return any.val
+}
+
+func (any *uint64Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *uint64Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *uint64Any) ToString() string {
+	return strconv.FormatUint(any.val, 10)
+}
+
+func (any *uint64Any) WriteTo(stream *Stream) {
+	stream.WriteUint64(any.val)
+}
+
+func (any *uint64Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *uint64Any) GetInterface() interface{} {
+	return any.val
+}
diff --git a/vendor/github.com/json-iterator/go/api_tests/config_test.go b/vendor/github.com/json-iterator/go/api_tests/config_test.go
new file mode 100644
index 000000000..7aa349bee
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/api_tests/config_test.go
@@ -0,0 +1,174 @@
+package test
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_use_number_for_unmarshal(t *testing.T) {
+	should := require.New(t)
+	api := jsoniter.Config{UseNumber: true}.Froze()
+	var obj interface{}
+	should.Nil(api.UnmarshalFromString("123", &obj))
+	should.Equal(json.Number("123"), obj)
+}
+
+func Test_customize_float_marshal(t *testing.T) {
+	should := require.New(t)
+	json := jsoniter.Config{MarshalFloatWith6Digits: true}.Froze()
+	str, err := json.MarshalToString(float32(1.23456789))
+	should.Nil(err)
+	should.Equal("1.234568", str)
+}
+
+func Test_customize_tag_key(t *testing.T) {
+
+	type TestObject struct {
+		Field string `orm:"field"`
+	}
+
+	should := require.New(t)
+	json := jsoniter.Config{TagKey: "orm"}.Froze()
+	str, err := json.MarshalToString(TestObject{"hello"})
+	should.Nil(err)
+	should.Equal(`{"field":"hello"}`, str)
+}
+
+func Test_read_large_number_as_interface(t *testing.T) {
+	should := require.New(t)
+	var val interface{}
+	err := jsoniter.Config{UseNumber: true}.Froze().UnmarshalFromString(`123456789123456789123456789`, &val)
+	should.Nil(err)
+	output, err := jsoniter.MarshalToString(val)
+	should.Nil(err)
+	should.Equal(`123456789123456789123456789`, output)
+}
+
+type caseSensitiveStruct struct {
+	A string `json:"a"`
+	B string `json:"b,omitempty"`
+	C *C     `json:"C,omitempty"`
+}
+
+type C struct {
+	D int64 `json:"D,omitempty"`
+	E *E    `json:"e,omitempty"`
+}
+
+type E struct {
+	F string `json:"F,omitempty"`
+}
+
+func Test_CaseSensitive(t *testing.T) {
+	should := require.New(t)
+
+	testCases := []struct {
+		input          string
+		expectedOutput string
+		caseSensitive  bool
+	}{
+		{
+			input:          `{"A":"foo","B":"bar"}`,
+			expectedOutput: `{"a":"foo","b":"bar"}`,
+			caseSensitive:  false,
+		},
+		{
+			input:          `{"a":"foo","b":"bar"}`,
+			expectedOutput: `{"a":"foo","b":"bar"}`,
+			caseSensitive:  true,
+		},
+		{
+			input:          `{"a":"foo","b":"bar","C":{"D":10}}`,
+			expectedOutput: `{"a":"foo","b":"bar","C":{"D":10}}`,
+			caseSensitive:  true,
+		},
+		{
+			input:          `{"a":"foo","B":"bar","c":{"d":10}}`,
+			expectedOutput: `{"a":"foo"}`,
+			caseSensitive:  true,
+		},
+		{
+			input:          `{"a":"foo","C":{"d":10}}`,
+			expectedOutput: `{"a":"foo","C":{}}`,
+			caseSensitive:  true,
+		},
+		{
+			input:          `{"a":"foo","C":{"D":10,"e":{"f":"baz"}}}`,
+			expectedOutput: `{"a":"foo","C":{"D":10,"e":{}}}`,
+			caseSensitive:  true,
+		},
+		{
+			input:          `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
+			expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
+			caseSensitive:  true,
+		},
+		{
+			input:          `{"A":"foo","c":{"d":10,"E":{"f":"baz"}}}`,
+			expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
+			caseSensitive:  false,
+		},
+	}
+
+	for _, tc := range testCases {
+		val := caseSensitiveStruct{}
+		err := jsoniter.Config{CaseSensitive: tc.caseSensitive}.Froze().UnmarshalFromString(tc.input, &val)
+		should.Nil(err)
+
+		output, err := jsoniter.MarshalToString(val)
+		should.Nil(err)
+		should.Equal(tc.expectedOutput, output)
+	}
+}
+
+type structWithElevenFields struct {
+	A string `json:"A,omitempty"`
+	B string `json:"B,omitempty"`
+	C string `json:"C,omitempty"`
+	D string `json:"d,omitempty"`
+	E string `json:"e,omitempty"`
+	F string `json:"f,omitempty"`
+	G string `json:"g,omitempty"`
+	H string `json:"h,omitempty"`
+	I string `json:"i,omitempty"`
+	J string `json:"j,omitempty"`
+	K string `json:"k,omitempty"`
+}
+
+func Test_CaseSensitive_MoreThanTenFields(t *testing.T) {
+	should := require.New(t)
+
+	testCases := []struct {
+		input          string
+		expectedOutput string
+		caseSensitive  bool
+	}{
+		{
+			input:          `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`,
+			expectedOutput: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`,
+			caseSensitive:  true,
+		},
+		{
+			input:          `{"a":"1","b":"2","c":"3","D":"4","E":"5","F":"6"}`,
+			expectedOutput: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6"}`,
+			caseSensitive:  false,
+		},
+		{
+			input:          `{"A":"1","b":"2","d":"4","E":"5"}`,
+			expectedOutput: `{"A":"1","d":"4"}`,
+			caseSensitive:  true,
+		},
+	}
+
+	for _, tc := range testCases {
+		val := structWithElevenFields{}
+		err := jsoniter.Config{CaseSensitive: tc.caseSensitive}.Froze().UnmarshalFromString(tc.input, &val)
+		should.Nil(err)
+
+		output, err := jsoniter.MarshalToString(val)
+		should.Nil(err)
+		should.Equal(tc.expectedOutput, output)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/api_tests/decoder_test.go b/vendor/github.com/json-iterator/go/api_tests/decoder_test.go
new file mode 100644
index 000000000..e325ef342
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/api_tests/decoder_test.go
@@ -0,0 +1,64 @@
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"io/ioutil"
+	"testing"
+)
+
+func Test_disallowUnknownFields(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct{}
+	var obj TestObject
+	decoder := jsoniter.NewDecoder(bytes.NewBufferString(`{"field1":100}`))
+	decoder.DisallowUnknownFields()
+	should.Error(decoder.Decode(&obj))
+}
+
+func Test_new_decoder(t *testing.T) {
+	should := require.New(t)
+	decoder1 := json.NewDecoder(bytes.NewBufferString(`[1][2]`))
+	decoder2 := jsoniter.NewDecoder(bytes.NewBufferString(`[1][2]`))
+	arr1 := []int{}
+	should.Nil(decoder1.Decode(&arr1))
+	should.Equal([]int{1}, arr1)
+	arr2 := []int{}
+	should.True(decoder1.More())
+	buffered, _ := ioutil.ReadAll(decoder1.Buffered())
+	should.Equal("[2]", string(buffered))
+	should.Nil(decoder2.Decode(&arr2))
+	should.Equal([]int{1}, arr2)
+	should.True(decoder2.More())
+	buffered, _ = ioutil.ReadAll(decoder2.Buffered())
+	should.Equal("[2]", string(buffered))
+
+	should.Nil(decoder1.Decode(&arr1))
+	should.Equal([]int{2}, arr1)
+	should.False(decoder1.More())
+	should.Nil(decoder2.Decode(&arr2))
+	should.Equal([]int{2}, arr2)
+	should.False(decoder2.More())
+}
+
+func Test_use_number(t *testing.T) {
+	should := require.New(t)
+	decoder1 := json.NewDecoder(bytes.NewBufferString(`123`))
+	decoder1.UseNumber()
+	decoder2 := jsoniter.NewDecoder(bytes.NewBufferString(`123`))
+	decoder2.UseNumber()
+	var obj1 interface{}
+	should.Nil(decoder1.Decode(&obj1))
+	should.Equal(json.Number("123"), obj1)
+	var obj2 interface{}
+	should.Nil(decoder2.Decode(&obj2))
+	should.Equal(json.Number("123"), obj2)
+}
+
+func Test_decoder_more(t *testing.T) {
+	should := require.New(t)
+	decoder := jsoniter.NewDecoder(bytes.NewBufferString("abcde"))
+	should.True(decoder.More())
+}
diff --git a/vendor/github.com/json-iterator/go/api_tests/encoder_18_test.go b/vendor/github.com/json-iterator/go/api_tests/encoder_18_test.go
new file mode 100644
index 000000000..3c159b58d
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/api_tests/encoder_18_test.go
@@ -0,0 +1,46 @@
+//+build go1.8
+
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"testing"
+	"unicode/utf8"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_new_encoder(t *testing.T) {
+	should := require.New(t)
+	buf1 := &bytes.Buffer{}
+	encoder1 := json.NewEncoder(buf1)
+	encoder1.SetEscapeHTML(false)
+	encoder1.Encode([]int{1})
+	should.Equal("[1]\n", buf1.String())
+	buf2 := &bytes.Buffer{}
+	encoder2 := jsoniter.NewEncoder(buf2)
+	encoder2.SetEscapeHTML(false)
+	encoder2.Encode([]int{1})
+	should.Equal("[1]\n", buf2.String())
+}
+
+func Test_string_encode_with_std_without_html_escape(t *testing.T) {
+	api := jsoniter.Config{EscapeHTML: false}.Froze()
+	should := require.New(t)
+	for i := 0; i < utf8.RuneSelf; i++ {
+		input := string([]byte{byte(i)})
+		buf := &bytes.Buffer{}
+		encoder := json.NewEncoder(buf)
+		encoder.SetEscapeHTML(false)
+		err := encoder.Encode(input)
+		should.Nil(err)
+		stdOutput := buf.String()
+		stdOutput = stdOutput[:len(stdOutput)-1]
+		jsoniterOutputBytes, err := api.Marshal(input)
+		should.Nil(err)
+		jsoniterOutput := string(jsoniterOutputBytes)
+		should.Equal(stdOutput, jsoniterOutput)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/api_tests/encoder_test.go b/vendor/github.com/json-iterator/go/api_tests/encoder_test.go
new file mode 100644
index 000000000..7b9202cf0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/api_tests/encoder_test.go
@@ -0,0 +1,20 @@
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+// Standard Encoder has trailing newline.
+func TestEncoderHasTrailingNewline(t *testing.T) {
+	should := require.New(t)
+	var buf, stdbuf bytes.Buffer
+	enc := jsoniter.ConfigCompatibleWithStandardLibrary.NewEncoder(&buf)
+	enc.Encode(1)
+	stdenc := json.NewEncoder(&stdbuf)
+	stdenc.Encode(1)
+	should.Equal(stdbuf.Bytes(), buf.Bytes())
+}
diff --git a/vendor/github.com/json-iterator/go/api_tests/marshal_indent_test.go b/vendor/github.com/json-iterator/go/api_tests/marshal_indent_test.go
new file mode 100644
index 000000000..926931a80
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/api_tests/marshal_indent_test.go
@@ -0,0 +1,36 @@
+package test
+
+import (
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func Test_marshal_indent(t *testing.T) {
+	should := require.New(t)
+	obj := struct {
+		F1 int
+		F2 []int
+	}{1, []int{2, 3, 4}}
+	output, err := json.MarshalIndent(obj, "", "  ")
+	should.Nil(err)
+	should.Equal("{\n  \"F1\": 1,\n  \"F2\": [\n    2,\n    3,\n    4\n  ]\n}", string(output))
+	output, err = jsoniter.MarshalIndent(obj, "", "  ")
+	should.Nil(err)
+	should.Equal("{\n  \"F1\": 1,\n  \"F2\": [\n    2,\n    3,\n    4\n  ]\n}", string(output))
+}
+
+func Test_marshal_indent_map(t *testing.T) {
+	should := require.New(t)
+	obj := map[int]int{1: 2}
+	output, err := json.MarshalIndent(obj, "", "  ")
+	should.Nil(err)
+	should.Equal("{\n  \"1\": 2\n}", string(output))
+	output, err = jsoniter.MarshalIndent(obj, "", "  ")
+	should.Nil(err)
+	should.Equal("{\n  \"1\": 2\n}", string(output))
+	output, err = jsoniter.ConfigCompatibleWithStandardLibrary.MarshalIndent(obj, "", "  ")
+	should.Nil(err)
+	should.Equal("{\n  \"1\": 2\n}", string(output))
+}
diff --git a/vendor/github.com/json-iterator/go/benchmarks/encode_string_test.go b/vendor/github.com/json-iterator/go/benchmarks/encode_string_test.go
new file mode 100644
index 000000000..c1cb1afb0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/benchmarks/encode_string_test.go
@@ -0,0 +1,25 @@
+package test
+
+import (
+	"bytes"
+	"github.com/json-iterator/go"
+	"testing"
+)
+
+func Benchmark_encode_string_with_SetEscapeHTML(b *testing.B) {
+	type V struct {
+		S string
+		B bool
+		I int
+	}
+	var json = jsoniter.ConfigCompatibleWithStandardLibrary
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		buf := &bytes.Buffer{}
+		enc := json.NewEncoder(buf)
+		enc.SetEscapeHTML(true)
+		if err := enc.Encode(V{S: "s", B: true, I: 233}); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/benchmarks/jsoniter_large_file_test.go b/vendor/github.com/json-iterator/go/benchmarks/jsoniter_large_file_test.go
new file mode 100644
index 000000000..465eaec91
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/benchmarks/jsoniter_large_file_test.go
@@ -0,0 +1,158 @@
+package test
+
+import (
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"io/ioutil"
+	"os"
+	"testing"
+)
+
+//func Test_large_file(t *testing.T) {
+//	file, err := os.Open("/tmp/large-file.json")
+//	if err != nil {
+//		t.Fatal(err)
+//	}
+//	iter := Parse(file, 4096)
+//	count := 0
+//	for iter.ReadArray() {
+//		iter.Skip()
+//		count++
+//	}
+//	if count != 11351 {
+//		t.Fatal(count)
+//	}
+//}
+
+func init() {
+	ioutil.WriteFile("/tmp/large-file.json", []byte(`[{
+  "person": {
+    "id": "d50887ca-a6ce-4e59-b89f-14f0b5d03b03",
+    "name": {
+      "fullName": "Leonid Bugaev",
+      "givenName": "Leonid",
+      "familyName": "Bugaev"
+    },
+    "email": "leonsbox@gmail.com",
+    "gender": "male",
+    "location": "Saint Petersburg, Saint Petersburg, RU",
+    "geo": {
+      "city": "Saint Petersburg",
+      "state": "Saint Petersburg",
+      "country": "Russia",
+      "lat": 59.9342802,
+      "lng": 30.3350986
+    },
+    "bio": "Senior engineer at Granify.com",
+    "site": "http://flickfaver.com",
+    "avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d50887ca-a6ce-4e59-b89f-14f0b5d03b03",
+    "employment": {
+      "name": "www.latera.ru",
+      "title": "Software Engineer",
+      "domain": "gmail.com"
+    },
+    "facebook": {
+      "handle": "leonid.bugaev"
+    },
+    "github": {
+      "handle": "buger",
+      "id": 14009,
+      "avatar": "https://avatars.githubusercontent.com/u/14009?v=3",
+      "company": "Granify",
+      "blog": "http://leonsbox.com",
+      "followers": 95,
+      "following": 10
+    },
+    "twitter": {
+      "handle": "flickfaver",
+      "id": 77004410,
+      "bio": null,
+      "followers": 2,
+      "following": 1,
+      "statuses": 5,
+      "favorites": 0,
+      "location": "",
+      "site": "http://flickfaver.com",
+      "avatar": null
+    },
+    "linkedin": {
+      "handle": "in/leonidbugaev"
+    },
+    "googleplus": {
+      "handle": null
+    },
+    "angellist": {
+      "handle": "leonid-bugaev",
+      "id": 61541,
+      "bio": "Senior engineer at Granify.com",
+      "blog": "http://buger.github.com",
+      "site": "http://buger.github.com",
+      "followers": 41,
+      "avatar": "https://d1qb2nb5cznatu.cloudfront.net/users/61541-medium_jpg?1405474390"
+    },
+    "klout": {
+      "handle": null,
+      "score": null
+    },
+    "foursquare": {
+      "handle": null
+    },
+    "aboutme": {
+      "handle": "leonid.bugaev",
+      "bio": null,
+      "avatar": null
+    },
+    "gravatar": {
+      "handle": "buger",
+      "urls": [
+      ],
+      "avatar": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510",
+      "avatars": [
+        {
+          "url": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510",
+          "type": "thumbnail"
+        }
+      ]
+    },
+    "fuzzy": false
+  },
+  "company": "hello"
+}]`), 0666)
+}
+
+/*
+200000	      8886 ns/op	    4336 B/op	       6 allocs/op
+50000	     34244 ns/op	    6744 B/op	      14 allocs/op
+*/
+func Benchmark_jsoniter_large_file(b *testing.B) {
+	b.ReportAllocs()
+	for n := 0; n < b.N; n++ {
+		file, _ := os.Open("/tmp/large-file.json")
+		iter := jsoniter.Parse(jsoniter.ConfigDefault, file, 4096)
+		count := 0
+		iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool {
+			// Skip() is strict by default, use --tags jsoniter-sloppy to skip without validation
+			iter.Skip()
+			count++
+			return true
+		})
+		file.Close()
+		if iter.Error != nil {
+			b.Error(iter.Error)
+		}
+	}
+}
+
+func Benchmark_json_large_file(b *testing.B) {
+	b.ReportAllocs()
+	for n := 0; n < b.N; n++ {
+		file, _ := os.Open("/tmp/large-file.json")
+		bytes, _ := ioutil.ReadAll(file)
+		file.Close()
+		result := []struct{}{}
+		err := json.Unmarshal(bytes, &result)
+		if err != nil {
+			b.Error(err)
+		}
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/build.sh b/vendor/github.com/json-iterator/go/build.sh
new file mode 100755
index 000000000..b45ef6883
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/build.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e
+set -x
+
+if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then
+    mkdir -p /tmp/build-golang/src/github.com/json-iterator
+    ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go
+fi
+export GOPATH=/tmp/build-golang
+go get -u github.com/golang/dep/cmd/dep
+cd /tmp/build-golang/src/github.com/json-iterator/go
+exec $GOPATH/bin/dep ensure -update
diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go
new file mode 100644
index 000000000..8c58fcba5
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/config.go
@@ -0,0 +1,375 @@
+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/example_test.go b/vendor/github.com/json-iterator/go/example_test.go
new file mode 100644
index 000000000..7f521a300
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/example_test.go
@@ -0,0 +1,121 @@
+package jsoniter
+
+import (
+	"fmt"
+	"os"
+	"strings"
+)
+
+func ExampleMarshal() {
+	type ColorGroup struct {
+		ID     int
+		Name   string
+		Colors []string
+	}
+	group := ColorGroup{
+		ID:     1,
+		Name:   "Reds",
+		Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
+	}
+	b, err := Marshal(group)
+	if err != nil {
+		fmt.Println("error:", err)
+	}
+	os.Stdout.Write(b)
+	// Output:
+	// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
+}
+
+func ExampleUnmarshal() {
+	var jsonBlob = []byte(`[
+		{"Name": "Platypus", "Order": "Monotremata"},
+		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
+	]`)
+	type Animal struct {
+		Name  string
+		Order string
+	}
+	var animals []Animal
+	err := Unmarshal(jsonBlob, &animals)
+	if err != nil {
+		fmt.Println("error:", err)
+	}
+	fmt.Printf("%+v", animals)
+	// Output:
+	// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
+}
+
+func ExampleConfigFastest_Marshal() {
+	type ColorGroup struct {
+		ID     int
+		Name   string
+		Colors []string
+	}
+	group := ColorGroup{
+		ID:     1,
+		Name:   "Reds",
+		Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
+	}
+	stream := ConfigFastest.BorrowStream(nil)
+	defer ConfigFastest.ReturnStream(stream)
+	stream.WriteVal(group)
+	if stream.Error != nil {
+		fmt.Println("error:", stream.Error)
+	}
+	os.Stdout.Write(stream.Buffer())
+	// Output:
+	// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
+}
+
+func ExampleConfigFastest_Unmarshal() {
+	var jsonBlob = []byte(`[
+		{"Name": "Platypus", "Order": "Monotremata"},
+		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
+	]`)
+	type Animal struct {
+		Name  string
+		Order string
+	}
+	var animals []Animal
+	iter := ConfigFastest.BorrowIterator(jsonBlob)
+	defer ConfigFastest.ReturnIterator(iter)
+	iter.ReadVal(&animals)
+	if iter.Error != nil {
+		fmt.Println("error:", iter.Error)
+	}
+	fmt.Printf("%+v", animals)
+	// Output:
+	// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
+}
+
+func ExampleGet() {
+	val := []byte(`{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}`)
+	fmt.Printf(Get(val, "Colors", 0).ToString())
+	// Output:
+	// Crimson
+}
+
+func ExampleMapKey() {
+	hello := MyKey("hello")
+	output, _ := Marshal(map[*MyKey]string{&hello: "world"})
+	fmt.Println(string(output))
+	obj := map[*MyKey]string{}
+	Unmarshal(output, &obj)
+	for k, v := range obj {
+		fmt.Println(*k, v)
+	}
+	// Output:
+	// {"Hello":"world"}
+	// Hel world
+}
+
+type MyKey string
+
+func (m *MyKey) MarshalText() ([]byte, error) {
+	return []byte(strings.Replace(string(*m), "h", "H", -1)), nil
+}
+
+func (m *MyKey) UnmarshalText(text []byte) error {
+	*m = MyKey(text[:3])
+	return nil
+}
diff --git a/vendor/github.com/json-iterator/go/extension_tests/decoder_test.go b/vendor/github.com/json-iterator/go/extension_tests/decoder_test.go
new file mode 100644
index 000000000..0f1dd30a0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extension_tests/decoder_test.go
@@ -0,0 +1,190 @@
+package test
+
+import (
+	"bytes"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"strconv"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+func Test_customize_type_decoder(t *testing.T) {
+	t.Skip()
+	jsoniter.RegisterTypeDecoderFunc("time.Time", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.UTC)
+		if err != nil {
+			iter.Error = err
+			return
+		}
+		*((*time.Time)(ptr)) = t
+	})
+	//defer jsoniter.ConfigDefault.(*frozenConfig).cleanDecoders()
+	val := time.Time{}
+	err := jsoniter.Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val)
+	if err != nil {
+		t.Fatal(err)
+	}
+	year, month, day := val.Date()
+	if year != 2016 || month != 12 || day != 5 {
+		t.Fatal(val)
+	}
+}
+
+func Test_customize_byte_array_encoder(t *testing.T) {
+	t.Skip()
+	//jsoniter.ConfigDefault.(*frozenConfig).cleanEncoders()
+	should := require.New(t)
+	jsoniter.RegisterTypeEncoderFunc("[]uint8", func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+		t := *((*[]byte)(ptr))
+		stream.WriteString(string(t))
+	}, nil)
+	//defer jsoniter.ConfigDefault.(*frozenConfig).cleanEncoders()
+	val := []byte("abc")
+	str, err := jsoniter.MarshalToString(val)
+	should.Nil(err)
+	should.Equal(`"abc"`, str)
+}
+
+func Test_customize_field_decoder(t *testing.T) {
+	type Tom struct {
+		field1 string
+	}
+	jsoniter.RegisterFieldDecoderFunc("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
+	})
+	//defer jsoniter.ConfigDefault.(*frozenConfig).cleanDecoders()
+	tom := Tom{}
+	err := jsoniter.Unmarshal([]byte(`{"field1": 100}`), &tom)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func Test_recursive_empty_interface_customization(t *testing.T) {
+	t.Skip()
+	var obj interface{}
+	jsoniter.RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		switch iter.WhatIsNext() {
+		case jsoniter.NumberValue:
+			*(*interface{})(ptr) = iter.ReadInt64()
+		default:
+			*(*interface{})(ptr) = iter.Read()
+		}
+	})
+	should := require.New(t)
+	jsoniter.Unmarshal([]byte("[100]"), &obj)
+	should.Equal([]interface{}{int64(100)}, obj)
+}
+
+type MyInterface interface {
+	Hello() string
+}
+
+type MyString string
+
+func (ms MyString) Hello() string {
+	return string(ms)
+}
+
+func Test_read_custom_interface(t *testing.T) {
+	t.Skip()
+	should := require.New(t)
+	var val MyInterface
+	jsoniter.RegisterTypeDecoderFunc("jsoniter.MyInterface", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		*((*MyInterface)(ptr)) = MyString(iter.ReadString())
+	})
+	err := jsoniter.UnmarshalFromString(`"hello"`, &val)
+	should.Nil(err)
+	should.Equal("hello", val.Hello())
+}
+
+const flow1 = `
+{"A":"hello"}
+{"A":"hello"}
+{"A":"hello"}
+{"A":"hello"}
+{"A":"hello"}`
+
+const flow2 = `
+{"A":"hello"}
+{"A":"hello"}
+{"A":"hello"}
+{"A":"hello"}
+{"A":"hello"}
+`
+
+type (
+	Type1 struct {
+		A string
+	}
+
+	Type2 struct {
+		A string
+	}
+)
+
+func (t *Type2) UnmarshalJSON(data []byte) error {
+	return nil
+}
+
+func (t *Type2) MarshalJSON() ([]byte, error) {
+	return nil, nil
+}
+
+func TestType1NoFinalLF(t *testing.T) {
+	reader := bytes.NewReader([]byte(flow1))
+	dec := jsoniter.NewDecoder(reader)
+
+	i := 0
+	for dec.More() {
+		data := &Type1{}
+		if err := dec.Decode(data); err != nil {
+			t.Errorf("at %v got %v", i, err)
+		}
+		i++
+	}
+}
+
+func TestType1FinalLF(t *testing.T) {
+	reader := bytes.NewReader([]byte(flow2))
+	dec := jsoniter.NewDecoder(reader)
+
+	i := 0
+	for dec.More() {
+		data := &Type1{}
+		if err := dec.Decode(data); err != nil {
+			t.Errorf("at %v got %v", i, err)
+		}
+		i++
+	}
+}
+
+func TestType2NoFinalLF(t *testing.T) {
+	reader := bytes.NewReader([]byte(flow1))
+	dec := jsoniter.NewDecoder(reader)
+
+	i := 0
+	for dec.More() {
+		data := &Type2{}
+		if err := dec.Decode(data); err != nil {
+			t.Errorf("at %v got %v", i, err)
+		}
+		i++
+	}
+}
+
+func TestType2FinalLF(t *testing.T) {
+	reader := bytes.NewReader([]byte(flow2))
+	dec := jsoniter.NewDecoder(reader)
+
+	i := 0
+	for dec.More() {
+		data := &Type2{}
+		if err := dec.Decode(data); err != nil {
+			t.Errorf("at %v got %v", i, err)
+		}
+		i++
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/extension_tests/extension_test.go b/vendor/github.com/json-iterator/go/extension_tests/extension_test.go
new file mode 100644
index 000000000..836db5bc0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extension_tests/extension_test.go
@@ -0,0 +1,120 @@
+package test
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/modern-go/reflect2"
+	"github.com/stretchr/testify/require"
+	"reflect"
+	"strconv"
+	"testing"
+	"unsafe"
+)
+
+type TestObject1 struct {
+	Field1 string
+}
+
+type testExtension struct {
+	jsoniter.DummyExtension
+}
+
+func (extension *testExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
+	if structDescriptor.Type.String() != "test.TestObject1" {
+		return
+	}
+	binding := structDescriptor.GetField("Field1")
+	binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+		str := *((*string)(ptr))
+		val, _ := strconv.Atoi(str)
+		stream.WriteInt(val)
+	}}
+	binding.Decoder = &funcDecoder{func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
+	}}
+	binding.ToNames = []string{"field-1"}
+	binding.FromNames = []string{"field-1"}
+}
+
+func Test_customize_field_by_extension(t *testing.T) {
+	should := require.New(t)
+	cfg := jsoniter.Config{}.Froze()
+	cfg.RegisterExtension(&testExtension{})
+	obj := TestObject1{}
+	err := cfg.UnmarshalFromString(`{"field-1": 100}`, &obj)
+	should.Nil(err)
+	should.Equal("100", obj.Field1)
+	str, err := cfg.MarshalToString(obj)
+	should.Nil(err)
+	should.Equal(`{"field-1":100}`, str)
+}
+
+func Test_customize_map_key_encoder(t *testing.T) {
+	should := require.New(t)
+	cfg := jsoniter.Config{}.Froze()
+	cfg.RegisterExtension(&testMapKeyExtension{})
+	m := map[int]int{1: 2}
+	output, err := cfg.MarshalToString(m)
+	should.NoError(err)
+	should.Equal(`{"2":2}`, output)
+	m = map[int]int{}
+	should.NoError(cfg.UnmarshalFromString(output, &m))
+	should.Equal(map[int]int{1: 2}, m)
+}
+
+type testMapKeyExtension struct {
+	jsoniter.DummyExtension
+}
+
+func (extension *testMapKeyExtension) CreateMapKeyEncoder(typ reflect2.Type) jsoniter.ValEncoder {
+	if typ.Kind() == reflect.Int {
+		return &funcEncoder{
+			fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+				stream.WriteRaw(`"`)
+				stream.WriteInt(*(*int)(ptr) + 1)
+				stream.WriteRaw(`"`)
+			},
+		}
+	}
+	return nil
+}
+
+func (extension *testMapKeyExtension) CreateMapKeyDecoder(typ reflect2.Type) jsoniter.ValDecoder {
+	if typ.Kind() == reflect.Int {
+		return &funcDecoder{
+			fun: func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+				i, err := strconv.Atoi(iter.ReadString())
+				if err != nil {
+					iter.ReportError("read map key", err.Error())
+					return
+				}
+				i--
+				*(*int)(ptr) = i
+			},
+		}
+	}
+	return nil
+}
+
+type funcDecoder struct {
+	fun jsoniter.DecoderFunc
+}
+
+func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	decoder.fun(ptr, iter)
+}
+
+type funcEncoder struct {
+	fun         jsoniter.EncoderFunc
+	isEmptyFunc func(ptr unsafe.Pointer) bool
+}
+
+func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+	encoder.fun(ptr, stream)
+}
+
+func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	if encoder.isEmptyFunc == nil {
+		return false
+	}
+	return encoder.isEmptyFunc(ptr)
+}
diff --git a/vendor/github.com/json-iterator/go/extra/binary_as_string_codec.go b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec.go
new file mode 100644
index 000000000..57d0ae5ba
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec.go
@@ -0,0 +1,238 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/modern-go/reflect2"
+	"unicode/utf8"
+	"unsafe"
+)
+
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      true,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      true,
+	'=':      true,
+	'>':      true,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
+
+var binaryType = reflect2.TypeOfPtr((*[]byte)(nil)).Elem()
+
+type BinaryAsStringExtension struct {
+	jsoniter.DummyExtension
+}
+
+func (extension *BinaryAsStringExtension) CreateEncoder(typ reflect2.Type) jsoniter.ValEncoder {
+	if typ == binaryType {
+		return &binaryAsStringCodec{}
+	}
+	return nil
+}
+
+func (extension *BinaryAsStringExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder {
+	if typ == binaryType {
+		return &binaryAsStringCodec{}
+	}
+	return nil
+}
+
+type binaryAsStringCodec struct {
+}
+
+func (codec *binaryAsStringCodec) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	rawBytes := iter.ReadStringAsSlice()
+	bytes := make([]byte, 0, len(rawBytes))
+	for i := 0; i < len(rawBytes); i++ {
+		b := rawBytes[i]
+		if b == '\\' {
+			b2 := rawBytes[i+1]
+			if b2 != '\\' {
+				iter.ReportError("decode binary as string", `\\x is only supported escape`)
+				return
+			}
+			b3 := rawBytes[i+2]
+			if b3 != 'x' {
+				iter.ReportError("decode binary as string", `\\x is only supported escape`)
+				return
+			}
+			b4 := rawBytes[i+3]
+			b5 := rawBytes[i+4]
+			i += 4
+			b = readHex(iter, b4, b5)
+		}
+		bytes = append(bytes, b)
+	}
+	*(*[]byte)(ptr) = bytes
+}
+func (codec *binaryAsStringCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*[]byte)(ptr))) == 0
+}
+func (codec *binaryAsStringCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+	newBuffer := writeBytes(stream.Buffer(), *(*[]byte)(ptr))
+	stream.SetBuffer(newBuffer)
+}
+
+func readHex(iter *jsoniter.Iterator, b1, b2 byte) byte {
+	var ret byte
+	if b1 >= '0' && b1 <= '9' {
+		ret = b1 - '0'
+	} else if b1 >= 'a' && b1 <= 'f' {
+		ret = b1 - 'a' + 10
+	} else {
+		iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b1}))
+		return 0
+	}
+	ret *= 16
+	if b2 >= '0' && b2 <= '9' {
+		ret = b2 - '0'
+	} else if b2 >= 'a' && b2 <= 'f' {
+		ret = b2 - 'a' + 10
+	} else {
+		iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b2}))
+		return 0
+	}
+	return ret
+}
+
+var hex = "0123456789abcdef"
+
+func writeBytes(space []byte, s []byte) []byte {
+	space = append(space, '"')
+	// write string, the fast path, without utf8 and escape support
+	var i int
+	var c byte
+	for i, c = range s {
+		if c < utf8.RuneSelf && safeSet[c] {
+			space = append(space, c)
+		} else {
+			break
+		}
+	}
+	if i == len(s)-1 {
+		space = append(space, '"')
+		return space
+	}
+	return writeBytesSlowPath(space, s[i:])
+}
+
+func writeBytesSlowPath(space []byte, s []byte) []byte {
+	start := 0
+	// for the remaining parts, we process them char by char
+	var i int
+	var b byte
+	for i, b = range s {
+		if b >= utf8.RuneSelf {
+			space = append(space, '\\', '\\', 'x', hex[b>>4], hex[b&0xF])
+			start = i + 1
+			continue
+		}
+		if safeSet[b] {
+			continue
+		}
+		if start < i {
+			space = append(space, s[start:i]...)
+		}
+		space = append(space, '\\', '\\', 'x', hex[b>>4], hex[b&0xF])
+		start = i + 1
+	}
+	if start < len(s) {
+		space = append(space, s[start:]...)
+	}
+	return append(space, '"')
+}
diff --git a/vendor/github.com/json-iterator/go/extra/binary_as_string_codec_test.go b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec_test.go
new file mode 100644
index 000000000..a00479e6c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec_test.go
@@ -0,0 +1,32 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func init() {
+	jsoniter.RegisterExtension(&BinaryAsStringExtension{})
+}
+
+func TestBinaryAsStringCodec(t *testing.T) {
+	t.Run("safe set", func(t *testing.T) {
+		should := require.New(t)
+		output, err := jsoniter.Marshal([]byte("hello"))
+		should.NoError(err)
+		should.Equal(`"hello"`, string(output))
+		var val []byte
+		should.NoError(jsoniter.Unmarshal(output, &val))
+		should.Equal(`hello`, string(val))
+	})
+	t.Run("non safe set", func(t *testing.T) {
+		should := require.New(t)
+		output, err := jsoniter.Marshal([]byte{1, 2, 3, 15})
+		should.NoError(err)
+		should.Equal(`"\\x01\\x02\\x03\\x0f"`, string(output))
+		var val []byte
+		should.NoError(jsoniter.Unmarshal(output, &val))
+		should.Equal([]byte{1, 2, 3, 15}, val)
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/extra/fuzzy_decoder.go b/vendor/github.com/json-iterator/go/extra/fuzzy_decoder.go
new file mode 100644
index 000000000..52546b11d
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/fuzzy_decoder.go
@@ -0,0 +1,294 @@
+package extra
+
+import (
+	"encoding/json"
+	"io"
+	"math"
+	"reflect"
+	"strings"
+	"unsafe"
+
+	"github.com/json-iterator/go"
+	"github.com/modern-go/reflect2"
+)
+
+const maxUint = ^uint(0)
+const maxInt = int(maxUint >> 1)
+const minInt = -maxInt - 1
+
+// RegisterFuzzyDecoders decode input from PHP with tolerance.
+// It will handle string/number auto conversation, and treat empty [] as empty struct.
+func RegisterFuzzyDecoders() {
+	jsoniter.RegisterExtension(&tolerateEmptyArrayExtension{})
+	jsoniter.RegisterTypeDecoder("string", &fuzzyStringDecoder{})
+	jsoniter.RegisterTypeDecoder("float32", &fuzzyFloat32Decoder{})
+	jsoniter.RegisterTypeDecoder("float64", &fuzzyFloat64Decoder{})
+	jsoniter.RegisterTypeDecoder("int", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(maxInt) || val < float64(minInt) {
+				iter.ReportError("fuzzy decode int", "exceed range")
+				return
+			}
+			*((*int)(ptr)) = int(val)
+		} else {
+			*((*int)(ptr)) = iter.ReadInt()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("uint", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(maxUint) || val < 0 {
+				iter.ReportError("fuzzy decode uint", "exceed range")
+				return
+			}
+			*((*uint)(ptr)) = uint(val)
+		} else {
+			*((*uint)(ptr)) = iter.ReadUint()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("int8", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxInt8) || val < float64(math.MinInt8) {
+				iter.ReportError("fuzzy decode int8", "exceed range")
+				return
+			}
+			*((*int8)(ptr)) = int8(val)
+		} else {
+			*((*int8)(ptr)) = iter.ReadInt8()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("uint8", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxUint8) || val < 0 {
+				iter.ReportError("fuzzy decode uint8", "exceed range")
+				return
+			}
+			*((*uint8)(ptr)) = uint8(val)
+		} else {
+			*((*uint8)(ptr)) = iter.ReadUint8()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("int16", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxInt16) || val < float64(math.MinInt16) {
+				iter.ReportError("fuzzy decode int16", "exceed range")
+				return
+			}
+			*((*int16)(ptr)) = int16(val)
+		} else {
+			*((*int16)(ptr)) = iter.ReadInt16()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("uint16", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxUint16) || val < 0 {
+				iter.ReportError("fuzzy decode uint16", "exceed range")
+				return
+			}
+			*((*uint16)(ptr)) = uint16(val)
+		} else {
+			*((*uint16)(ptr)) = iter.ReadUint16()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("int32", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxInt32) || val < float64(math.MinInt32) {
+				iter.ReportError("fuzzy decode int32", "exceed range")
+				return
+			}
+			*((*int32)(ptr)) = int32(val)
+		} else {
+			*((*int32)(ptr)) = iter.ReadInt32()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("uint32", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxUint32) || val < 0 {
+				iter.ReportError("fuzzy decode uint32", "exceed range")
+				return
+			}
+			*((*uint32)(ptr)) = uint32(val)
+		} else {
+			*((*uint32)(ptr)) = iter.ReadUint32()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("int64", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxInt64) || val < float64(math.MinInt64) {
+				iter.ReportError("fuzzy decode int64", "exceed range")
+				return
+			}
+			*((*int64)(ptr)) = int64(val)
+		} else {
+			*((*int64)(ptr)) = iter.ReadInt64()
+		}
+	}})
+	jsoniter.RegisterTypeDecoder("uint64", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+		if isFloat {
+			val := iter.ReadFloat64()
+			if val > float64(math.MaxUint64) || val < 0 {
+				iter.ReportError("fuzzy decode uint64", "exceed range")
+				return
+			}
+			*((*uint64)(ptr)) = uint64(val)
+		} else {
+			*((*uint64)(ptr)) = iter.ReadUint64()
+		}
+	}})
+}
+
+type tolerateEmptyArrayExtension struct {
+	jsoniter.DummyExtension
+}
+
+func (extension *tolerateEmptyArrayExtension) DecorateDecoder(typ reflect2.Type, decoder jsoniter.ValDecoder) jsoniter.ValDecoder {
+	if typ.Kind() == reflect.Struct || typ.Kind() == reflect.Map {
+		return &tolerateEmptyArrayDecoder{decoder}
+	}
+	return decoder
+}
+
+type tolerateEmptyArrayDecoder struct {
+	valDecoder jsoniter.ValDecoder
+}
+
+func (decoder *tolerateEmptyArrayDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	if iter.WhatIsNext() == jsoniter.ArrayValue {
+		iter.Skip()
+		newIter := iter.Pool().BorrowIterator([]byte("{}"))
+		defer iter.Pool().ReturnIterator(newIter)
+		decoder.valDecoder.Decode(ptr, newIter)
+	} else {
+		decoder.valDecoder.Decode(ptr, iter)
+	}
+}
+
+type fuzzyStringDecoder struct {
+}
+
+func (decoder *fuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	valueType := iter.WhatIsNext()
+	switch valueType {
+	case jsoniter.NumberValue:
+		var number json.Number
+		iter.ReadVal(&number)
+		*((*string)(ptr)) = string(number)
+	case jsoniter.StringValue:
+		*((*string)(ptr)) = iter.ReadString()
+	case jsoniter.NilValue:
+		iter.Skip()
+		*((*string)(ptr)) = ""
+	default:
+		iter.ReportError("fuzzyStringDecoder", "not number or string")
+	}
+}
+
+type fuzzyIntegerDecoder struct {
+	fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator)
+}
+
+func (decoder *fuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	valueType := iter.WhatIsNext()
+	var str string
+	switch valueType {
+	case jsoniter.NumberValue:
+		var number json.Number
+		iter.ReadVal(&number)
+		str = string(number)
+	case jsoniter.StringValue:
+		str = iter.ReadString()
+	case jsoniter.BoolValue:
+		if iter.ReadBool() {
+			str = "1"
+		} else {
+			str = "0"
+		}
+	case jsoniter.NilValue:
+		iter.Skip()
+		str = "0"
+	default:
+		iter.ReportError("fuzzyIntegerDecoder", "not number or string")
+	}
+	if len(str) == 0 {
+		str = "0"
+	}
+	newIter := iter.Pool().BorrowIterator([]byte(str))
+	defer iter.Pool().ReturnIterator(newIter)
+	isFloat := strings.IndexByte(str, '.') != -1
+	decoder.fun(isFloat, ptr, newIter)
+	if newIter.Error != nil && newIter.Error != io.EOF {
+		iter.Error = newIter.Error
+	}
+}
+
+type fuzzyFloat32Decoder struct {
+}
+
+func (decoder *fuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	valueType := iter.WhatIsNext()
+	var str string
+	switch valueType {
+	case jsoniter.NumberValue:
+		*((*float32)(ptr)) = iter.ReadFloat32()
+	case jsoniter.StringValue:
+		str = iter.ReadString()
+		newIter := iter.Pool().BorrowIterator([]byte(str))
+		defer iter.Pool().ReturnIterator(newIter)
+		*((*float32)(ptr)) = newIter.ReadFloat32()
+		if newIter.Error != nil && newIter.Error != io.EOF {
+			iter.Error = newIter.Error
+		}
+	case jsoniter.BoolValue:
+		// support bool to float32
+		if iter.ReadBool() {
+			*((*float32)(ptr)) = 1
+		} else {
+			*((*float32)(ptr)) = 0
+		}
+	case jsoniter.NilValue:
+		iter.Skip()
+		*((*float32)(ptr)) = 0
+	default:
+		iter.ReportError("fuzzyFloat32Decoder", "not number or string")
+	}
+}
+
+type fuzzyFloat64Decoder struct {
+}
+
+func (decoder *fuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	valueType := iter.WhatIsNext()
+	var str string
+	switch valueType {
+	case jsoniter.NumberValue:
+		*((*float64)(ptr)) = iter.ReadFloat64()
+	case jsoniter.StringValue:
+		str = iter.ReadString()
+		newIter := iter.Pool().BorrowIterator([]byte(str))
+		defer iter.Pool().ReturnIterator(newIter)
+		*((*float64)(ptr)) = newIter.ReadFloat64()
+		if newIter.Error != nil && newIter.Error != io.EOF {
+			iter.Error = newIter.Error
+		}
+	case jsoniter.BoolValue:
+		// support bool to float64
+		if iter.ReadBool() {
+			*((*float64)(ptr)) = 1
+		} else {
+			*((*float64)(ptr)) = 0
+		}
+	case jsoniter.NilValue:
+		iter.Skip()
+		*((*float64)(ptr)) = 0
+	default:
+		iter.ReportError("fuzzyFloat64Decoder", "not number or string")
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/extra/fuzzy_decoder_test.go b/vendor/github.com/json-iterator/go/extra/fuzzy_decoder_test.go
new file mode 100644
index 000000000..69315adfb
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/fuzzy_decoder_test.go
@@ -0,0 +1,393 @@
+package extra
+
+import (
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func init() {
+	RegisterFuzzyDecoders()
+}
+
+func Test_any_to_string(t *testing.T) {
+	should := require.New(t)
+	var val string
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal("100", val)
+	should.Nil(jsoniter.UnmarshalFromString("10", &val))
+	should.Equal("10", val)
+	should.Nil(jsoniter.UnmarshalFromString("10.1", &val))
+	should.Equal("10.1", val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal("10.1", val)
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+}
+func Test_any_to_int64(t *testing.T) {
+	should := require.New(t)
+	var val int64
+
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(int64(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(int64(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(int64(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(int64(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`""`, &val))
+	should.Equal(int64(0), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(int64(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(int64(1), val)
+
+	should.Nil(jsoniter.UnmarshalFromString(`-10`, &val))
+	should.Equal(int64(-10), val)
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+
+func Test_any_to_int(t *testing.T) {
+	should := require.New(t)
+	var val int
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(100, val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(10, val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(10, val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(10, val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(0, val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(1, val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+
+func Test_any_to_int16(t *testing.T) {
+	should := require.New(t)
+	var val int16
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(int16(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(int16(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(int16(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(int16(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(int16(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(int16(1), val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+
+func Test_any_to_int32(t *testing.T) {
+	should := require.New(t)
+	var val int32
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(int32(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(int32(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(int32(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(int32(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(int32(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(int32(1), val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+
+func Test_any_to_int8(t *testing.T) {
+	should := require.New(t)
+	var val int8
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(int8(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(int8(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(int8(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(int8(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(int8(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(int8(1), val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+
+func Test_any_to_uint8(t *testing.T) {
+	should := require.New(t)
+	var val uint8
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(uint8(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(uint8(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(uint8(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(uint8(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(uint8(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(uint8(1), val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+
+func Test_any_to_uint64(t *testing.T) {
+	should := require.New(t)
+	var val uint64
+
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(uint64(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(uint64(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(uint64(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(uint64(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(uint64(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(uint64(1), val)
+
+	// TODO fix?
+	should.NotNil(jsoniter.UnmarshalFromString(`-10`, &val))
+	should.Equal(uint64(0), val)
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+func Test_any_to_uint32(t *testing.T) {
+	should := require.New(t)
+	var val uint32
+
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(uint32(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(uint32(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(uint32(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(uint32(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(uint32(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(uint32(1), val)
+
+	// TODO fix?
+	should.NotNil(jsoniter.UnmarshalFromString(`-10`, &val))
+	should.Equal(uint32(0), val)
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+func Test_any_to_uint16(t *testing.T) {
+	should := require.New(t)
+	var val uint16
+
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(uint16(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(uint16(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(uint16(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(uint16(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(uint16(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(uint16(1), val)
+
+	// TODO fix?
+	should.NotNil(jsoniter.UnmarshalFromString(`-10`, &val))
+	should.Equal(uint16(0), val)
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+func Test_any_to_uint(t *testing.T) {
+	should := require.New(t)
+	var val uint
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(uint(100), val)
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(uint(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(uint(10), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(uint(10), val)
+
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(uint(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(uint(1), val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+	// large float to int
+	should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val))
+}
+
+func Test_any_to_float32(t *testing.T) {
+	should := require.New(t)
+	var val float32
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(float32(100), val)
+
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(float32(10.1), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(float32(10.1), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(float32(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(float32(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(float32(1), val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+}
+
+func Test_any_to_float64(t *testing.T) {
+	should := require.New(t)
+	var val float64
+
+	should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val))
+	should.Equal(float64(100), val)
+
+	should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val))
+	should.Equal(float64(10.1), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
+	should.Equal(float64(10.1), val)
+	should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
+	should.Equal(float64(10), val)
+
+	// bool part
+	should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
+	should.Equal(float64(0), val)
+	should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
+	should.Equal(float64(1), val)
+
+	should.NotNil(jsoniter.UnmarshalFromString("{}", &val))
+	should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
+}
+
+func Test_empty_array_as_map(t *testing.T) {
+	should := require.New(t)
+	var val map[string]interface{}
+	should.Nil(jsoniter.UnmarshalFromString(`[]`, &val))
+	should.Equal(map[string]interface{}{}, val)
+}
+
+func Test_empty_array_as_object(t *testing.T) {
+	should := require.New(t)
+	var val struct{}
+	should.Nil(jsoniter.UnmarshalFromString(`[]`, &val))
+	should.Equal(struct{}{}, val)
+}
+
+func Test_bad_case(t *testing.T) {
+	var jsonstr = `
+{
+    "extra_type": 181760,
+    "combo_type": 0,
+    "trigger_time_ms": 1498800398000,
+    "_create_time": "2017-06-16 11:21:39",
+    "_msg_type": 41000
+}
+`
+
+	type OrderEventRequestParams struct {
+		ExtraType uint64 `json:"extra_type"`
+	}
+
+	var a OrderEventRequestParams
+	err := jsoniter.UnmarshalFromString(jsonstr, &a)
+	should := require.New(t)
+	should.Nil(err)
+}
+
+func Test_null_to_string(t *testing.T) {
+	should := require.New(t)
+	body := []byte(`null`)
+	var message string
+	err := jsoniter.Unmarshal(body, &message)
+	should.NoError(err)
+}
+
+func Test_null_to_int(t *testing.T) {
+	should := require.New(t)
+	body := []byte(`null`)
+	var message int
+	err := jsoniter.Unmarshal(body, &message)
+	should.NoError(err)
+}
+
+func Test_null_to_float32(t *testing.T) {
+	should := require.New(t)
+	body := []byte(`null`)
+	var message float32
+	err := jsoniter.Unmarshal(body, &message)
+	should.NoError(err)
+}
+
+func Test_null_to_float64(t *testing.T) {
+	should := require.New(t)
+	body := []byte(`null`)
+	var message float64
+	err := jsoniter.Unmarshal(body, &message)
+	should.NoError(err)
+}
diff --git a/vendor/github.com/json-iterator/go/extra/naming_strategy.go b/vendor/github.com/json-iterator/go/extra/naming_strategy.go
new file mode 100644
index 000000000..2390f6571
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/naming_strategy.go
@@ -0,0 +1,52 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"strings"
+	"unicode"
+)
+
+// SetNamingStrategy rename struct fields uniformly
+func SetNamingStrategy(translate func(string) string) {
+	jsoniter.RegisterExtension(&namingStrategyExtension{jsoniter.DummyExtension{}, translate})
+}
+
+type namingStrategyExtension struct {
+	jsoniter.DummyExtension
+	translate func(string) string
+}
+
+func (extension *namingStrategyExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
+	for _, binding := range structDescriptor.Fields {
+		tag, hastag := binding.Field.Tag().Lookup("json")
+		if hastag {
+			tagParts := strings.Split(tag, ",")
+			if tagParts[0] == "-" {
+				continue // hidden field
+			}
+			if tagParts[0] != "" {
+				continue // field explicitly named
+			}
+		}
+		binding.ToNames = []string{extension.translate(binding.Field.Name())}
+		binding.FromNames = []string{extension.translate(binding.Field.Name())}
+	}
+}
+
+// LowerCaseWithUnderscores one strategy to SetNamingStrategy for. It will change HelloWorld to hello_world.
+func LowerCaseWithUnderscores(name string) string {
+	newName := []rune{}
+	for i, c := range name {
+		if i == 0 {
+			newName = append(newName, unicode.ToLower(c))
+		} else {
+			if unicode.IsUpper(c) {
+				newName = append(newName, '_')
+				newName = append(newName, unicode.ToLower(c))
+			} else {
+				newName = append(newName, c)
+			}
+		}
+	}
+	return string(newName)
+}
diff --git a/vendor/github.com/json-iterator/go/extra/naming_strategy_test.go b/vendor/github.com/json-iterator/go/extra/naming_strategy_test.go
new file mode 100644
index 000000000..bee7803e7
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/naming_strategy_test.go
@@ -0,0 +1,50 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func Test_lower_case_with_underscores(t *testing.T) {
+	should := require.New(t)
+	should.Equal("hello_world", LowerCaseWithUnderscores("helloWorld"))
+	should.Equal("hello_world", LowerCaseWithUnderscores("HelloWorld"))
+	SetNamingStrategy(LowerCaseWithUnderscores)
+	output, err := jsoniter.Marshal(struct {
+		UserName      string
+		FirstLanguage string
+	}{
+		UserName:      "taowen",
+		FirstLanguage: "Chinese",
+	})
+	should.Nil(err)
+	should.Equal(`{"user_name":"taowen","first_language":"Chinese"}`, string(output))
+}
+
+func Test_set_naming_strategy_with_overrides(t *testing.T) {
+	should := require.New(t)
+	SetNamingStrategy(LowerCaseWithUnderscores)
+	output, err := jsoniter.Marshal(struct {
+		UserName      string `json:"UserName"`
+		FirstLanguage string
+	}{
+		UserName:      "taowen",
+		FirstLanguage: "Chinese",
+	})
+	should.Nil(err)
+	should.Equal(`{"UserName":"taowen","first_language":"Chinese"}`, string(output))
+}
+
+func Test_set_naming_strategy_with_omitempty(t *testing.T) {
+	should := require.New(t)
+	SetNamingStrategy(LowerCaseWithUnderscores)
+	output, err := jsoniter.Marshal(struct {
+		UserName      string
+		FirstLanguage string `json:",omitempty"`
+	}{
+		UserName: "taowen",
+	})
+	should.Nil(err)
+	should.Equal(`{"user_name":"taowen"}`, string(output))
+}
diff --git a/vendor/github.com/json-iterator/go/extra/privat_fields.go b/vendor/github.com/json-iterator/go/extra/privat_fields.go
new file mode 100644
index 000000000..cbebe5cd8
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/privat_fields.go
@@ -0,0 +1,54 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"strings"
+	"unicode"
+)
+
+// SupportPrivateFields include private fields when encoding/decoding
+func SupportPrivateFields() {
+	jsoniter.RegisterExtension(&privateFieldsExtension{})
+}
+
+type privateFieldsExtension struct {
+	jsoniter.DummyExtension
+}
+
+func (extension *privateFieldsExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
+	for _, binding := range structDescriptor.Fields {
+		isPrivate := unicode.IsLower(rune(binding.Field.Name()[0]))
+		if isPrivate {
+			tag, hastag := binding.Field.Tag().Lookup("json")
+			if !hastag {
+				binding.FromNames = []string{binding.Field.Name()}
+				binding.ToNames = []string{binding.Field.Name()}
+				continue
+			}
+			tagParts := strings.Split(tag, ",")
+			names := calcFieldNames(binding.Field.Name(), tagParts[0], tag)
+			binding.FromNames = names
+			binding.ToNames = names
+		}
+	}
+}
+
+func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string {
+	// ignore?
+	if wholeTag == "-" {
+		return []string{}
+	}
+	// rename?
+	var fieldNames []string
+	if tagProvidedFieldName == "" {
+		fieldNames = []string{originalFieldName}
+	} else {
+		fieldNames = []string{tagProvidedFieldName}
+	}
+	// private?
+	isNotExported := unicode.IsLower(rune(originalFieldName[0]))
+	if isNotExported {
+		fieldNames = []string{}
+	}
+	return fieldNames
+}
diff --git a/vendor/github.com/json-iterator/go/extra/private_fields_test.go b/vendor/github.com/json-iterator/go/extra/private_fields_test.go
new file mode 100644
index 000000000..d3bc40dac
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/private_fields_test.go
@@ -0,0 +1,18 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func Test_private_fields(t *testing.T) {
+	type TestObject struct {
+		field1 string
+	}
+	SupportPrivateFields()
+	should := require.New(t)
+	obj := TestObject{}
+	should.Nil(jsoniter.UnmarshalFromString(`{"field1":"Hello"}`, &obj))
+	should.Equal("Hello", obj.field1)
+}
diff --git a/vendor/github.com/json-iterator/go/extra/time_as_int64_codec.go b/vendor/github.com/json-iterator/go/extra/time_as_int64_codec.go
new file mode 100644
index 000000000..9893872a0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/time_as_int64_codec.go
@@ -0,0 +1,31 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"time"
+	"unsafe"
+)
+
+// RegisterTimeAsInt64Codec encode/decode time since number of unit since epoch. the precision is the unit.
+func RegisterTimeAsInt64Codec(precision time.Duration) {
+	jsoniter.RegisterTypeEncoder("time.Time", &timeAsInt64Codec{precision})
+	jsoniter.RegisterTypeDecoder("time.Time", &timeAsInt64Codec{precision})
+}
+
+type timeAsInt64Codec struct {
+	precision time.Duration
+}
+
+func (codec *timeAsInt64Codec) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	nanoseconds := iter.ReadInt64() * codec.precision.Nanoseconds()
+	*((*time.Time)(ptr)) = time.Unix(0, nanoseconds)
+}
+
+func (codec *timeAsInt64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	ts := *((*time.Time)(ptr))
+	return ts.UnixNano() == 0
+}
+func (codec *timeAsInt64Codec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+	ts := *((*time.Time)(ptr))
+	stream.WriteInt64(ts.UnixNano() / codec.precision.Nanoseconds())
+}
diff --git a/vendor/github.com/json-iterator/go/extra/time_as_int64_codec_test.go b/vendor/github.com/json-iterator/go/extra/time_as_int64_codec_test.go
new file mode 100644
index 000000000..b27220f18
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/extra/time_as_int64_codec_test.go
@@ -0,0 +1,31 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"testing"
+	"time"
+)
+
+func Test_time_as_int64(t *testing.T) {
+	should := require.New(t)
+	RegisterTimeAsInt64Codec(time.Nanosecond)
+	output, err := jsoniter.Marshal(time.Unix(1497952257, 1002))
+	should.Nil(err)
+	should.Equal("1497952257000001002", string(output))
+	var val time.Time
+	should.Nil(jsoniter.Unmarshal(output, &val))
+	should.Equal(int64(1497952257000001002), val.UnixNano())
+}
+
+func Test_time_as_int64_keep_microsecond(t *testing.T) {
+	t.Skip("conflict")
+	should := require.New(t)
+	RegisterTimeAsInt64Codec(time.Microsecond)
+	output, err := jsoniter.Marshal(time.Unix(1, 1002))
+	should.Nil(err)
+	should.Equal("1000001", string(output))
+	var val time.Time
+	should.Nil(jsoniter.Unmarshal(output, &val))
+	should.Equal(int64(1000001000), val.UnixNano())
+}
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/iter.go b/vendor/github.com/json-iterator/go/iter.go
new file mode 100644
index 000000000..95ae54fbf
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter.go
@@ -0,0 +1,322 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+)
+
+// ValueType the type for JSON element
+type ValueType int
+
+const (
+	// InvalidValue invalid JSON element
+	InvalidValue ValueType = iota
+	// StringValue JSON element "string"
+	StringValue
+	// NumberValue JSON element 100 or 0.10
+	NumberValue
+	// NilValue JSON element null
+	NilValue
+	// BoolValue JSON element true or false
+	BoolValue
+	// ArrayValue JSON element []
+	ArrayValue
+	// ObjectValue JSON element {}
+	ObjectValue
+)
+
+var hexDigits []byte
+var valueTypes []ValueType
+
+func init() {
+	hexDigits = make([]byte, 256)
+	for i := 0; i < len(hexDigits); i++ {
+		hexDigits[i] = 255
+	}
+	for i := '0'; i <= '9'; i++ {
+		hexDigits[i] = byte(i - '0')
+	}
+	for i := 'a'; i <= 'f'; i++ {
+		hexDigits[i] = byte((i - 'a') + 10)
+	}
+	for i := 'A'; i <= 'F'; i++ {
+		hexDigits[i] = byte((i - 'A') + 10)
+	}
+	valueTypes = make([]ValueType, 256)
+	for i := 0; i < len(valueTypes); i++ {
+		valueTypes[i] = InvalidValue
+	}
+	valueTypes['"'] = StringValue
+	valueTypes['-'] = NumberValue
+	valueTypes['0'] = NumberValue
+	valueTypes['1'] = NumberValue
+	valueTypes['2'] = NumberValue
+	valueTypes['3'] = NumberValue
+	valueTypes['4'] = NumberValue
+	valueTypes['5'] = NumberValue
+	valueTypes['6'] = NumberValue
+	valueTypes['7'] = NumberValue
+	valueTypes['8'] = NumberValue
+	valueTypes['9'] = NumberValue
+	valueTypes['t'] = BoolValue
+	valueTypes['f'] = BoolValue
+	valueTypes['n'] = NilValue
+	valueTypes['['] = ArrayValue
+	valueTypes['{'] = ObjectValue
+}
+
+// Iterator is a io.Reader like object, with JSON specific read functions.
+// Error is not returned as return value, but stored as Error member on this iterator instance.
+type Iterator struct {
+	cfg              *frozenConfig
+	reader           io.Reader
+	buf              []byte
+	head             int
+	tail             int
+	captureStartedAt int
+	captured         []byte
+	Error            error
+	Attachment       interface{} // open for customized decoder
+}
+
+// NewIterator creates an empty Iterator instance
+func NewIterator(cfg API) *Iterator {
+	return &Iterator{
+		cfg:    cfg.(*frozenConfig),
+		reader: nil,
+		buf:    nil,
+		head:   0,
+		tail:   0,
+	}
+}
+
+// Parse creates an Iterator instance from io.Reader
+func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
+	return &Iterator{
+		cfg:    cfg.(*frozenConfig),
+		reader: reader,
+		buf:    make([]byte, bufSize),
+		head:   0,
+		tail:   0,
+	}
+}
+
+// ParseBytes creates an Iterator instance from byte array
+func ParseBytes(cfg API, input []byte) *Iterator {
+	return &Iterator{
+		cfg:    cfg.(*frozenConfig),
+		reader: nil,
+		buf:    input,
+		head:   0,
+		tail:   len(input),
+	}
+}
+
+// ParseString creates an Iterator instance from string
+func ParseString(cfg API, input string) *Iterator {
+	return ParseBytes(cfg, []byte(input))
+}
+
+// Pool returns a pool can provide more iterator with same configuration
+func (iter *Iterator) Pool() IteratorPool {
+	return iter.cfg
+}
+
+// Reset reuse iterator instance by specifying another reader
+func (iter *Iterator) Reset(reader io.Reader) *Iterator {
+	iter.reader = reader
+	iter.head = 0
+	iter.tail = 0
+	return iter
+}
+
+// ResetBytes reuse iterator instance by specifying another byte array as input
+func (iter *Iterator) ResetBytes(input []byte) *Iterator {
+	iter.reader = nil
+	iter.buf = input
+	iter.head = 0
+	iter.tail = len(input)
+	return iter
+}
+
+// WhatIsNext gets ValueType of relatively next json element
+func (iter *Iterator) WhatIsNext() ValueType {
+	valueType := valueTypes[iter.nextToken()]
+	iter.unreadByte()
+	return valueType
+}
+
+func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		switch c {
+		case ' ', '\n', '\t', '\r':
+			continue
+		}
+		iter.head = i
+		return false
+	}
+	return true
+}
+
+func (iter *Iterator) isObjectEnd() bool {
+	c := iter.nextToken()
+	if c == ',' {
+		return false
+	}
+	if c == '}' {
+		return true
+	}
+	iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
+	return true
+}
+
+func (iter *Iterator) nextToken() byte {
+	// a variation of skip whitespaces, returning the next non-whitespace token
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case ' ', '\n', '\t', '\r':
+				continue
+			}
+			iter.head = i + 1
+			return c
+		}
+		if !iter.loadMore() {
+			return 0
+		}
+	}
+}
+
+// ReportError record a error in iterator instance with current position.
+func (iter *Iterator) ReportError(operation string, msg string) {
+	if iter.Error != nil {
+		if iter.Error != io.EOF {
+			return
+		}
+	}
+	peekStart := iter.head - 10
+	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)
+}
+
+// CurrentBuffer gets current buffer as string for debugging purpose
+func (iter *Iterator) CurrentBuffer() string {
+	peekStart := iter.head - 10
+	if peekStart < 0 {
+		peekStart = 0
+	}
+	return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
+		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
+}
+
+func (iter *Iterator) readByte() (ret byte) {
+	if iter.head == iter.tail {
+		if iter.loadMore() {
+			ret = iter.buf[iter.head]
+			iter.head++
+			return ret
+		}
+		return 0
+	}
+	ret = iter.buf[iter.head]
+	iter.head++
+	return ret
+}
+
+func (iter *Iterator) loadMore() bool {
+	if iter.reader == nil {
+		if iter.Error == nil {
+			iter.head = iter.tail
+			iter.Error = io.EOF
+		}
+		return false
+	}
+	if iter.captured != nil {
+		iter.captured = append(iter.captured,
+			iter.buf[iter.captureStartedAt:iter.tail]...)
+		iter.captureStartedAt = 0
+	}
+	for {
+		n, err := iter.reader.Read(iter.buf)
+		if n == 0 {
+			if err != nil {
+				if iter.Error == nil {
+					iter.Error = err
+				}
+				return false
+			}
+		} else {
+			iter.head = 0
+			iter.tail = n
+			return true
+		}
+	}
+}
+
+func (iter *Iterator) unreadByte() {
+	if iter.Error != nil {
+		return
+	}
+	iter.head--
+	return
+}
+
+// Read read the next JSON element as generic interface{}.
+func (iter *Iterator) Read() interface{} {
+	valueType := iter.WhatIsNext()
+	switch valueType {
+	case StringValue:
+		return iter.ReadString()
+	case NumberValue:
+		if iter.cfg.configBeforeFrozen.UseNumber {
+			return json.Number(iter.readNumberAsString())
+		}
+		return iter.ReadFloat64()
+	case NilValue:
+		iter.skipFourBytes('n', 'u', 'l', 'l')
+		return nil
+	case BoolValue:
+		return iter.ReadBool()
+	case ArrayValue:
+		arr := []interface{}{}
+		iter.ReadArrayCB(func(iter *Iterator) bool {
+			var elem interface{}
+			iter.ReadVal(&elem)
+			arr = append(arr, elem)
+			return true
+		})
+		return arr
+	case ObjectValue:
+		obj := map[string]interface{}{}
+		iter.ReadMapCB(func(Iter *Iterator, field string) bool {
+			var elem interface{}
+			iter.ReadVal(&elem)
+			obj[field] = elem
+			return true
+		})
+		return obj
+	default:
+		iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
+		return nil
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go
new file mode 100644
index 000000000..6188cb457
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_array.go
@@ -0,0 +1,58 @@
+package jsoniter
+
+// ReadArray read array element, tells if the array has more element to read.
+func (iter *Iterator) ReadArray() (ret bool) {
+	c := iter.nextToken()
+	switch c {
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l')
+		return false // null
+	case '[':
+		c = iter.nextToken()
+		if c != ']' {
+			iter.unreadByte()
+			return true
+		}
+		return false
+	case ']':
+		return false
+	case ',':
+		return true
+	default:
+		iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c}))
+		return
+	}
+}
+
+// ReadArrayCB read array with callback
+func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
+	c := iter.nextToken()
+	if c == '[' {
+		c = iter.nextToken()
+		if c != ']' {
+			iter.unreadByte()
+			if !callback(iter) {
+				return false
+			}
+			c = iter.nextToken()
+			for c == ',' {
+				if !callback(iter) {
+					return false
+				}
+				c = iter.nextToken()
+			}
+			if c != ']' {
+				iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c}))
+				return false
+			}
+			return true
+		}
+		return true
+	}
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return true // null
+	}
+	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/iter_float.go
new file mode 100644
index 000000000..3ccd757cb
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_float.go
@@ -0,0 +1,343 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"io"
+	"math/big"
+	"strconv"
+	"strings"
+	"unsafe"
+)
+
+var floatDigits []int8
+
+const invalidCharForNumber = int8(-1)
+const endOfNumber = int8(-2)
+const dotInNumber = int8(-3)
+
+func init() {
+	floatDigits = make([]int8, 256)
+	for i := 0; i < len(floatDigits); i++ {
+		floatDigits[i] = invalidCharForNumber
+	}
+	for i := int8('0'); i <= int8('9'); i++ {
+		floatDigits[i] = i - int8('0')
+	}
+	floatDigits[','] = endOfNumber
+	floatDigits[']'] = endOfNumber
+	floatDigits['}'] = endOfNumber
+	floatDigits[' '] = endOfNumber
+	floatDigits['\t'] = endOfNumber
+	floatDigits['\n'] = endOfNumber
+	floatDigits['.'] = dotInNumber
+}
+
+// ReadBigFloat read big.Float
+func (iter *Iterator) ReadBigFloat() (ret *big.Float) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return nil
+	}
+	prec := 64
+	if len(str) > prec {
+		prec = len(str)
+	}
+	val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero)
+	if err != nil {
+		iter.Error = err
+		return nil
+	}
+	return val
+}
+
+// ReadBigInt read big.Int
+func (iter *Iterator) ReadBigInt() (ret *big.Int) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return nil
+	}
+	ret = big.NewInt(0)
+	var success bool
+	ret, success = ret.SetString(str, 10)
+	if !success {
+		iter.ReportError("ReadBigInt", "invalid big int")
+		return nil
+	}
+	return ret
+}
+
+//ReadFloat32 read float32
+func (iter *Iterator) ReadFloat32() (ret float32) {
+	c := iter.nextToken()
+	if c == '-' {
+		return -iter.readPositiveFloat32()
+	}
+	iter.unreadByte()
+	return iter.readPositiveFloat32()
+}
+
+func (iter *Iterator) readPositiveFloat32() (ret float32) {
+	value := uint64(0)
+	c := byte(' ')
+	i := iter.head
+	// first char
+	if i == iter.tail {
+		return iter.readFloat32SlowPath()
+	}
+	c = iter.buf[i]
+	i++
+	ind := floatDigits[c]
+	switch ind {
+	case invalidCharForNumber:
+		return iter.readFloat32SlowPath()
+	case endOfNumber:
+		iter.ReportError("readFloat32", "empty number")
+		return
+	case dotInNumber:
+		iter.ReportError("readFloat32", "leading dot is invalid")
+		return
+	case 0:
+		if i == iter.tail {
+			return iter.readFloat32SlowPath()
+		}
+		c = iter.buf[i]
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			iter.ReportError("readFloat32", "leading zero is invalid")
+			return
+		}
+	}
+	value = uint64(ind)
+	// chars before dot
+non_decimal_loop:
+	for ; i < iter.tail; i++ {
+		c = iter.buf[i]
+		ind := floatDigits[c]
+		switch ind {
+		case invalidCharForNumber:
+			return iter.readFloat32SlowPath()
+		case endOfNumber:
+			iter.head = i
+			return float32(value)
+		case dotInNumber:
+			break non_decimal_loop
+		}
+		if value > uint64SafeToMultiple10 {
+			return iter.readFloat32SlowPath()
+		}
+		value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
+	}
+	// chars after dot
+	if c == '.' {
+		i++
+		decimalPlaces := 0
+		if i == iter.tail {
+			return iter.readFloat32SlowPath()
+		}
+		for ; i < iter.tail; i++ {
+			c = iter.buf[i]
+			ind := floatDigits[c]
+			switch ind {
+			case endOfNumber:
+				if decimalPlaces > 0 && decimalPlaces < len(pow10) {
+					iter.head = i
+					return float32(float64(value) / float64(pow10[decimalPlaces]))
+				}
+				// too many decimal places
+				return iter.readFloat32SlowPath()
+			case invalidCharForNumber, dotInNumber:
+				return iter.readFloat32SlowPath()
+			}
+			decimalPlaces++
+			if value > uint64SafeToMultiple10 {
+				return iter.readFloat32SlowPath()
+			}
+			value = (value << 3) + (value << 1) + uint64(ind)
+		}
+	}
+	return iter.readFloat32SlowPath()
+}
+
+func (iter *Iterator) readNumberAsString() (ret string) {
+	strBuf := [16]byte{}
+	str := strBuf[0:0]
+load_loop:
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+				str = append(str, c)
+				continue
+			default:
+				iter.head = i
+				break load_loop
+			}
+		}
+		if !iter.loadMore() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		return
+	}
+	if len(str) == 0 {
+		iter.ReportError("readNumberAsString", "invalid number")
+	}
+	return *(*string)(unsafe.Pointer(&str))
+}
+
+func (iter *Iterator) readFloat32SlowPath() (ret float32) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return
+	}
+	errMsg := validateFloat(str)
+	if errMsg != "" {
+		iter.ReportError("readFloat32SlowPath", errMsg)
+		return
+	}
+	val, err := strconv.ParseFloat(str, 32)
+	if err != nil {
+		iter.Error = err
+		return
+	}
+	return float32(val)
+}
+
+// ReadFloat64 read float64
+func (iter *Iterator) ReadFloat64() (ret float64) {
+	c := iter.nextToken()
+	if c == '-' {
+		return -iter.readPositiveFloat64()
+	}
+	iter.unreadByte()
+	return iter.readPositiveFloat64()
+}
+
+func (iter *Iterator) readPositiveFloat64() (ret float64) {
+	value := uint64(0)
+	c := byte(' ')
+	i := iter.head
+	// first char
+	if i == iter.tail {
+		return iter.readFloat64SlowPath()
+	}
+	c = iter.buf[i]
+	i++
+	ind := floatDigits[c]
+	switch ind {
+	case invalidCharForNumber:
+		return iter.readFloat64SlowPath()
+	case endOfNumber:
+		iter.ReportError("readFloat64", "empty number")
+		return
+	case dotInNumber:
+		iter.ReportError("readFloat64", "leading dot is invalid")
+		return
+	case 0:
+		if i == iter.tail {
+			return iter.readFloat64SlowPath()
+		}
+		c = iter.buf[i]
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			iter.ReportError("readFloat64", "leading zero is invalid")
+			return
+		}
+	}
+	value = uint64(ind)
+	// chars before dot
+non_decimal_loop:
+	for ; i < iter.tail; i++ {
+		c = iter.buf[i]
+		ind := floatDigits[c]
+		switch ind {
+		case invalidCharForNumber:
+			return iter.readFloat64SlowPath()
+		case endOfNumber:
+			iter.head = i
+			return float64(value)
+		case dotInNumber:
+			break non_decimal_loop
+		}
+		if value > uint64SafeToMultiple10 {
+			return iter.readFloat64SlowPath()
+		}
+		value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
+	}
+	// chars after dot
+	if c == '.' {
+		i++
+		decimalPlaces := 0
+		if i == iter.tail {
+			return iter.readFloat64SlowPath()
+		}
+		for ; i < iter.tail; i++ {
+			c = iter.buf[i]
+			ind := floatDigits[c]
+			switch ind {
+			case endOfNumber:
+				if decimalPlaces > 0 && decimalPlaces < len(pow10) {
+					iter.head = i
+					return float64(value) / float64(pow10[decimalPlaces])
+				}
+				// too many decimal places
+				return iter.readFloat64SlowPath()
+			case invalidCharForNumber, dotInNumber:
+				return iter.readFloat64SlowPath()
+			}
+			decimalPlaces++
+			if value > uint64SafeToMultiple10 {
+				return iter.readFloat64SlowPath()
+			}
+			value = (value << 3) + (value << 1) + uint64(ind)
+		}
+	}
+	return iter.readFloat64SlowPath()
+}
+
+func (iter *Iterator) readFloat64SlowPath() (ret float64) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return
+	}
+	errMsg := validateFloat(str)
+	if errMsg != "" {
+		iter.ReportError("readFloat64SlowPath", errMsg)
+		return
+	}
+	val, err := strconv.ParseFloat(str, 64)
+	if err != nil {
+		iter.Error = err
+		return
+	}
+	return val
+}
+
+func validateFloat(str string) string {
+	// strconv.ParseFloat is not validating `1.` or `1.e1`
+	if len(str) == 0 {
+		return "empty number"
+	}
+	if str[0] == '-' {
+		return "-- is not valid"
+	}
+	dotPos := strings.IndexByte(str, '.')
+	if dotPos != -1 {
+		if dotPos == len(str)-1 {
+			return "dot can not be last character"
+		}
+		switch str[dotPos+1] {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		default:
+			return "missing digit after dot"
+		}
+	}
+	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/iter_int.go
new file mode 100644
index 000000000..214232035
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_int.go
@@ -0,0 +1,345 @@
+package jsoniter
+
+import (
+	"math"
+	"strconv"
+)
+
+var intDigits []int8
+
+const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
+const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
+
+func init() {
+	intDigits = make([]int8, 256)
+	for i := 0; i < len(intDigits); i++ {
+		intDigits[i] = invalidCharForNumber
+	}
+	for i := int8('0'); i <= int8('9'); i++ {
+		intDigits[i] = i - int8('0')
+	}
+}
+
+// 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())
+}
+
+// ReadInt8 read int8
+func (iter *Iterator) ReadInt8() (ret int8) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint32(iter.readByte())
+		if val > math.MaxInt8+1 {
+			iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
+			return
+		}
+		return -int8(val)
+	}
+	val := iter.readUint32(c)
+	if val > math.MaxInt8 {
+		iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return int8(val)
+}
+
+// ReadUint8 read uint8
+func (iter *Iterator) ReadUint8() (ret uint8) {
+	val := iter.readUint32(iter.nextToken())
+	if val > math.MaxUint8 {
+		iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return uint8(val)
+}
+
+// ReadInt16 read int16
+func (iter *Iterator) ReadInt16() (ret int16) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint32(iter.readByte())
+		if val > math.MaxInt16+1 {
+			iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
+			return
+		}
+		return -int16(val)
+	}
+	val := iter.readUint32(c)
+	if val > math.MaxInt16 {
+		iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return int16(val)
+}
+
+// ReadUint16 read uint16
+func (iter *Iterator) ReadUint16() (ret uint16) {
+	val := iter.readUint32(iter.nextToken())
+	if val > math.MaxUint16 {
+		iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return uint16(val)
+}
+
+// ReadInt32 read int32
+func (iter *Iterator) ReadInt32() (ret int32) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint32(iter.readByte())
+		if val > math.MaxInt32+1 {
+			iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
+			return
+		}
+		return -int32(val)
+	}
+	val := iter.readUint32(c)
+	if val > math.MaxInt32 {
+		iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return int32(val)
+}
+
+// ReadUint32 read uint32
+func (iter *Iterator) ReadUint32() (ret uint32) {
+	return iter.readUint32(iter.nextToken())
+}
+
+func (iter *Iterator) readUint32(c byte) (ret uint32) {
+	ind := intDigits[c]
+	if ind == 0 {
+		iter.assertInteger()
+		return 0 // single zero
+	}
+	if ind == invalidCharForNumber {
+		iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)}))
+		return
+	}
+	value := uint32(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 + uint32(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 + 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++
+		ind9 := intDigits[iter.buf[i]]
+		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
+		}
+	}
+	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 > uint32SafeToMultiply10 {
+				value2 := (value << 3) + (value << 1) + uint32(ind)
+				if value2 < value {
+					iter.ReportError("readUint32", "overflow")
+					return
+				}
+				value = value2
+				continue
+			}
+			value = (value << 3) + (value << 1) + uint32(ind)
+		}
+		if !iter.loadMore() {
+			iter.assertInteger()
+			return value
+		}
+	}
+}
+
+// ReadInt64 read int64
+func (iter *Iterator) ReadInt64() (ret int64) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint64(iter.readByte())
+		if val > math.MaxInt64+1 {
+			iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
+			return
+		}
+		return -int64(val)
+	}
+	val := iter.readUint64(c)
+	if val > math.MaxInt64 {
+		iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
+		return
+	}
+	return int64(val)
+}
+
+// ReadUint64 read uint64
+func (iter *Iterator) ReadUint64() uint64 {
+	return iter.readUint64(iter.nextToken())
+}
+
+func (iter *Iterator) readUint64(c byte) (ret uint64) {
+	ind := intDigits[c]
+	if ind == 0 {
+		iter.assertInteger()
+		return 0 // single zero
+	}
+	if ind == invalidCharForNumber {
+		iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)}))
+		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 {
+				value2 := (value << 3) + (value << 1) + uint64(ind)
+				if value2 < value {
+					iter.ReportError("readUint64", "overflow")
+					return
+				}
+				value = value2
+				continue
+			}
+			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/iter_object.go
new file mode 100644
index 000000000..1c5757671
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_object.go
@@ -0,0 +1,251 @@
+package jsoniter
+
+import (
+	"fmt"
+	"strings"
+)
+
+// ReadObject read one field from object.
+// If object ended, returns empty string.
+// Otherwise, returns the field name.
+func (iter *Iterator) ReadObject() (ret string) {
+	c := iter.nextToken()
+	switch c {
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l')
+		return "" // null
+	case '{':
+		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
+		}
+		if c == '}' {
+			return "" // end of object
+		}
+		iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c}))
+		return
+	case ',':
+		field := iter.ReadString()
+		c = iter.nextToken()
+		if c != ':' {
+			iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+		}
+		return field
+	case '}':
+		return "" // end of object
+	default:
+		iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c})))
+		return
+	}
+}
+
+// CaseInsensitive
+func (iter *Iterator) readFieldHash() int64 {
+	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
+				}
+				return hash
+			}
+			if b == '"' {
+				iter.head = i + 1
+				c = iter.nextToken()
+				if c != ':' {
+					iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
+					return 0
+				}
+				return hash
+			}
+			if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
+				b += 'a' - 'A'
+			}
+			hash ^= int64(b)
+			hash *= 0x1000193
+		}
+		if !iter.loadMore() {
+			iter.ReportError("readFieldHash", `incomplete field name`)
+			return 0
+		}
+	}
+}
+
+func calcHash(str string, caseSensitive bool) int64 {
+	if !caseSensitive {
+		str = strings.ToLower(str)
+	}
+	hash := int64(0x811c9dc5)
+	for _, b := range []byte(str) {
+		hash ^= int64(b)
+		hash *= 0x1000193
+	}
+	return int64(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) {
+				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) {
+					return false
+				}
+				c = iter.nextToken()
+			}
+			if c != '}' {
+				iter.ReportError("ReadObjectCB", `object not ended with }`)
+				return false
+			}
+			return true
+		}
+		if c == '}' {
+			return true
+		}
+		iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c}))
+		return false
+	}
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return true // null
+	}
+	iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c}))
+	return false
+}
+
+// ReadMapCB read map with callback, the key can be any string
+func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
+	c := iter.nextToken()
+	if c == '{' {
+		c = iter.nextToken()
+		if c == '"' {
+			iter.unreadByte()
+			field := iter.ReadString()
+			if iter.nextToken() != ':' {
+				iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+				return false
+			}
+			if !callback(iter, field) {
+				return false
+			}
+			c = iter.nextToken()
+			for c == ',' {
+				field = iter.ReadString()
+				if iter.nextToken() != ':' {
+					iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+					return false
+				}
+				if !callback(iter, field) {
+					return false
+				}
+				c = iter.nextToken()
+			}
+			if c != '}' {
+				iter.ReportError("ReadMapCB", `object not ended with }`)
+				return false
+			}
+			return true
+		}
+		if c == '}' {
+			return true
+		}
+		iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
+		return false
+	}
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return true // null
+	}
+	iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
+	return false
+}
+
+func (iter *Iterator) readObjectStart() bool {
+	c := iter.nextToken()
+	if c == '{' {
+		c = iter.nextToken()
+		if c == '}' {
+			return false
+		}
+		iter.unreadByte()
+		return true
+	} else if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return false
+	}
+	iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c}))
+	return false
+}
+
+func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) {
+	str := iter.ReadStringAsSlice()
+	if iter.skipWhitespacesWithoutLoadMore() {
+		if ret == nil {
+			ret = make([]byte, len(str))
+			copy(ret, str)
+		}
+		if !iter.loadMore() {
+			return
+		}
+	}
+	if iter.buf[iter.head] != ':' {
+		iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]}))
+		return
+	}
+	iter.head++
+	if iter.skipWhitespacesWithoutLoadMore() {
+		if ret == nil {
+			ret = make([]byte, len(str))
+			copy(ret, str)
+		}
+		if !iter.loadMore() {
+			return
+		}
+	}
+	if ret == nil {
+		return str
+	}
+	return ret
+}
diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go
new file mode 100644
index 000000000..f58beb913
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_skip.go
@@ -0,0 +1,129 @@
+package jsoniter
+
+import "fmt"
+
+// ReadNil reads a json object as nil and
+// returns whether it's a nil or not
+func (iter *Iterator) ReadNil() (ret bool) {
+	c := iter.nextToken()
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l') // null
+		return true
+	}
+	iter.unreadByte()
+	return false
+}
+
+// ReadBool reads a json object as BoolValue
+func (iter *Iterator) ReadBool() (ret bool) {
+	c := iter.nextToken()
+	if c == 't' {
+		iter.skipThreeBytes('r', 'u', 'e')
+		return true
+	}
+	if c == 'f' {
+		iter.skipFourBytes('a', 'l', 's', 'e')
+		return false
+	}
+	iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
+	return
+}
+
+// SkipAndReturnBytes skip next JSON element, and return its content as []byte.
+// The []byte can be kept, it is a copy of data.
+func (iter *Iterator) SkipAndReturnBytes() []byte {
+	iter.startCapture(iter.head)
+	iter.Skip()
+	return iter.stopCapture()
+}
+
+type captureBuffer struct {
+	startedAt int
+	captured  []byte
+}
+
+func (iter *Iterator) startCapture(captureStartedAt int) {
+	if iter.captured != nil {
+		panic("already in capture mode")
+	}
+	iter.captureStartedAt = captureStartedAt
+	iter.captured = make([]byte, 0, 32)
+}
+
+func (iter *Iterator) stopCapture() []byte {
+	if iter.captured == nil {
+		panic("not in capture mode")
+	}
+	captured := iter.captured
+	remaining := iter.buf[iter.captureStartedAt:iter.head]
+	iter.captureStartedAt = -1
+	iter.captured = nil
+	if len(captured) == 0 {
+		copied := make([]byte, len(remaining))
+		copy(copied, remaining)
+		return copied
+	}
+	captured = append(captured, remaining...)
+	return captured
+}
+
+// Skip skips a json object and positions to relatively the next json object
+func (iter *Iterator) Skip() {
+	c := iter.nextToken()
+	switch c {
+	case '"':
+		iter.skipString()
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l') // null
+	case 't':
+		iter.skipThreeBytes('r', 'u', 'e') // true
+	case 'f':
+		iter.skipFourBytes('a', 'l', 's', 'e') // false
+	case '0':
+		iter.unreadByte()
+		iter.ReadFloat32()
+	case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		iter.skipNumber()
+	case '[':
+		iter.skipArray()
+	case '{':
+		iter.skipObject()
+	default:
+		iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
+		return
+	}
+}
+
+func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) {
+	if iter.readByte() != b1 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+	if iter.readByte() != b2 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+	if iter.readByte() != b3 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+	if iter.readByte() != b4 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+}
+
+func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) {
+	if iter.readByte() != b1 {
+		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
+		return
+	}
+	if iter.readByte() != b2 {
+		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
+		return
+	}
+	if iter.readByte() != b3 {
+		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
+		return
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go
new file mode 100644
index 000000000..8fcdc3b69
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go
@@ -0,0 +1,144 @@
+//+build jsoniter_sloppy
+
+package jsoniter
+
+// sloppy but faster implementation, do not validate the input json
+
+func (iter *Iterator) skipNumber() {
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case ' ', '\n', '\r', '\t', ',', '}', ']':
+				iter.head = i
+				return
+			}
+		}
+		if !iter.loadMore() {
+			return
+		}
+	}
+}
+
+func (iter *Iterator) skipArray() {
+	level := 1
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			switch iter.buf[i] {
+			case '"': // If inside string, skip it
+				iter.head = i + 1
+				iter.skipString()
+				i = iter.head - 1 // it will be i++ soon
+			case '[': // If open symbol, increase level
+				level++
+			case ']': // If close symbol, increase level
+				level--
+
+				// If we have returned to the original level, we're done
+				if level == 0 {
+					iter.head = i + 1
+					return
+				}
+			}
+		}
+		if !iter.loadMore() {
+			iter.ReportError("skipObject", "incomplete array")
+			return
+		}
+	}
+}
+
+func (iter *Iterator) skipObject() {
+	level := 1
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			switch iter.buf[i] {
+			case '"': // If inside string, skip it
+				iter.head = i + 1
+				iter.skipString()
+				i = iter.head - 1 // it will be i++ soon
+			case '{': // If open symbol, increase level
+				level++
+			case '}': // If close symbol, increase level
+				level--
+
+				// If we have returned to the original level, we're done
+				if level == 0 {
+					iter.head = i + 1
+					return
+				}
+			}
+		}
+		if !iter.loadMore() {
+			iter.ReportError("skipObject", "incomplete object")
+			return
+		}
+	}
+}
+
+func (iter *Iterator) skipString() {
+	for {
+		end, escaped := iter.findStringEnd()
+		if end == -1 {
+			if !iter.loadMore() {
+				iter.ReportError("skipString", "incomplete string")
+				return
+			}
+			if escaped {
+				iter.head = 1 // skip the first char as last char read is \
+			}
+		} else {
+			iter.head = end
+			return
+		}
+	}
+}
+
+// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
+// Tries to find the end of string
+// Support if string contains escaped quote symbols.
+func (iter *Iterator) findStringEnd() (int, bool) {
+	escaped := false
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		if c == '"' {
+			if !escaped {
+				return i + 1, false
+			}
+			j := i - 1
+			for {
+				if j < iter.head || iter.buf[j] != '\\' {
+					// even number of backslashes
+					// either end of buffer, or " found
+					return i + 1, true
+				}
+				j--
+				if j < iter.head || iter.buf[j] != '\\' {
+					// odd number of backslashes
+					// it is \" or \\\"
+					break
+				}
+				j--
+			}
+		} else if c == '\\' {
+			escaped = true
+		}
+	}
+	j := iter.tail - 1
+	for {
+		if j < iter.head || iter.buf[j] != '\\' {
+			// even number of backslashes
+			// either end of buffer, or " found
+			return -1, false // do not end with \
+		}
+		j--
+		if j < iter.head || iter.buf[j] != '\\' {
+			// odd number of backslashes
+			// it is \" or \\\"
+			break
+		}
+		j--
+
+	}
+	return -1, true // end with \
+}
diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy_test.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy_test.go
new file mode 100644
index 000000000..bcb491fe6
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_skip_sloppy_test.go
@@ -0,0 +1,162 @@
+//+build jsoniter_sloppy
+
+package jsoniter
+
+import (
+	"github.com/stretchr/testify/require"
+	"io"
+	"testing"
+)
+
+func Test_string_end(t *testing.T) {
+	end, escaped := ParseString(ConfigDefault, `abc"`).findStringEnd()
+	if end != 4 {
+		t.Fatal(end)
+	}
+	if escaped != false {
+		t.Fatal(escaped)
+	}
+	end, escaped = ParseString(ConfigDefault, `abc\\"`).findStringEnd()
+	if end != 6 {
+		t.Fatal(end)
+	}
+	if escaped != true {
+		t.Fatal(escaped)
+	}
+	end, escaped = ParseString(ConfigDefault, `abc\\\\"`).findStringEnd()
+	if end != 8 {
+		t.Fatal(end)
+	}
+	if escaped != true {
+		t.Fatal(escaped)
+	}
+	end, escaped = ParseString(ConfigDefault, `abc\"`).findStringEnd()
+	if end != -1 {
+		t.Fatal(end)
+	}
+	if escaped != false {
+		t.Fatal(escaped)
+	}
+	end, escaped = ParseString(ConfigDefault, `abc\`).findStringEnd()
+	if end != -1 {
+		t.Fatal(end)
+	}
+	if escaped != true {
+		t.Fatal(escaped)
+	}
+	end, escaped = ParseString(ConfigDefault, `abc\\`).findStringEnd()
+	if end != -1 {
+		t.Fatal(end)
+	}
+	if escaped != false {
+		t.Fatal(escaped)
+	}
+	end, escaped = ParseString(ConfigDefault, `\\`).findStringEnd()
+	if end != -1 {
+		t.Fatal(end)
+	}
+	if escaped != false {
+		t.Fatal(escaped)
+	}
+	end, escaped = ParseString(ConfigDefault, `\`).findStringEnd()
+	if end != -1 {
+		t.Fatal(end)
+	}
+	if escaped != true {
+		t.Fatal(escaped)
+	}
+}
+
+type StagedReader struct {
+	r1 string
+	r2 string
+	r3 string
+	r  int
+}
+
+func (reader *StagedReader) Read(p []byte) (n int, err error) {
+	reader.r++
+	switch reader.r {
+	case 1:
+		copy(p, []byte(reader.r1))
+		return len(reader.r1), nil
+	case 2:
+		copy(p, []byte(reader.r2))
+		return len(reader.r2), nil
+	case 3:
+		copy(p, []byte(reader.r3))
+		return len(reader.r3), nil
+	default:
+		return 0, io.EOF
+	}
+}
+
+func Test_skip_string(t *testing.T) {
+	should := require.New(t)
+	iter := ParseString(ConfigDefault, `"abc`)
+	iter.skipString()
+	should.Equal(1, iter.head)
+	iter = ParseString(ConfigDefault, `\""abc`)
+	iter.skipString()
+	should.Equal(3, iter.head)
+	reader := &StagedReader{
+		r1: `abc`,
+		r2: `"`,
+	}
+	iter = Parse(ConfigDefault, reader, 4096)
+	iter.skipString()
+	should.Equal(1, iter.head)
+	reader = &StagedReader{
+		r1: `abc`,
+		r2: `1"`,
+	}
+	iter = Parse(ConfigDefault, reader, 4096)
+	iter.skipString()
+	should.Equal(2, iter.head)
+	reader = &StagedReader{
+		r1: `abc\`,
+		r2: `"`,
+	}
+	iter = Parse(ConfigDefault, reader, 4096)
+	iter.skipString()
+	should.NotNil(iter.Error)
+	reader = &StagedReader{
+		r1: `abc\`,
+		r2: `""`,
+	}
+	iter = Parse(ConfigDefault, reader, 4096)
+	iter.skipString()
+	should.Equal(2, iter.head)
+}
+
+func Test_skip_object(t *testing.T) {
+	iter := ParseString(ConfigDefault, `}`)
+	iter.skipObject()
+	if iter.head != 1 {
+		t.Fatal(iter.head)
+	}
+	iter = ParseString(ConfigDefault, `a}`)
+	iter.skipObject()
+	if iter.head != 2 {
+		t.Fatal(iter.head)
+	}
+	iter = ParseString(ConfigDefault, `{}}a`)
+	iter.skipObject()
+	if iter.head != 3 {
+		t.Fatal(iter.head)
+	}
+	reader := &StagedReader{
+		r1: `{`,
+		r2: `}}a`,
+	}
+	iter = Parse(ConfigDefault, reader, 4096)
+	iter.skipObject()
+	if iter.head != 2 {
+		t.Fatal(iter.head)
+	}
+	iter = ParseString(ConfigDefault, `"}"}a`)
+	iter.skipObject()
+	if iter.head != 4 {
+		t.Fatal(iter.head)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go
new file mode 100644
index 000000000..f67bc2e83
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_skip_strict.go
@@ -0,0 +1,89 @@
+//+build !jsoniter_sloppy
+
+package jsoniter
+
+import "fmt"
+
+func (iter *Iterator) skipNumber() {
+	if !iter.trySkipNumber() {
+		iter.unreadByte()
+		iter.ReadFloat32()
+	}
+}
+
+func (iter *Iterator) trySkipNumber() bool {
+	dotFound := false
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		case '.':
+			if dotFound {
+				iter.ReportError("validateNumber", `more than one dot found in number`)
+				return true // already failed
+			}
+			if i+1 == iter.tail {
+				return false
+			}
+			c = iter.buf[i+1]
+			switch c {
+			case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			default:
+				iter.ReportError("validateNumber", `missing digit after dot`)
+				return true // already failed
+			}
+			dotFound = true
+		default:
+			switch c {
+			case ',', ']', '}', ' ', '\t', '\n', '\r':
+				if iter.head == i {
+					return false // if - without following digits
+				}
+				iter.head = i
+				return true // must be valid
+			}
+			return false // may be invalid
+		}
+	}
+	return false
+}
+
+func (iter *Iterator) skipString() {
+	if !iter.trySkipString() {
+		iter.unreadByte()
+		iter.ReadString()
+	}
+}
+
+func (iter *Iterator) trySkipString() bool {
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		if c == '"' {
+			iter.head = i + 1
+			return true // valid
+		} else if c == '\\' {
+			return false
+		} else if c < ' ' {
+			iter.ReportError("trySkipString",
+				fmt.Sprintf(`invalid control character found: %d`, c))
+			return true // already failed
+		}
+	}
+	return false
+}
+
+func (iter *Iterator) skipObject() {
+	iter.unreadByte()
+	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		iter.Skip()
+		return true
+	})
+}
+
+func (iter *Iterator) skipArray() {
+	iter.unreadByte()
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		iter.Skip()
+		return true
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/iter_str.go
new file mode 100644
index 000000000..adc487ea8
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/iter_str.go
@@ -0,0 +1,215 @@
+package jsoniter
+
+import (
+	"fmt"
+	"unicode/utf16"
+)
+
+// ReadString read string from iterator
+func (iter *Iterator) ReadString() (ret string) {
+	c := iter.nextToken()
+	if c == '"' {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			if c == '"' {
+				ret = string(iter.buf[iter.head:i])
+				iter.head = i + 1
+				return ret
+			} else if c == '\\' {
+				break
+			} else if c < ' ' {
+				iter.ReportError("ReadString",
+					fmt.Sprintf(`invalid control character found: %d`, c))
+				return
+			}
+		}
+		return iter.readStringSlowPath()
+	} else if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return ""
+	}
+	iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c}))
+	return
+}
+
+func (iter *Iterator) readStringSlowPath() (ret string) {
+	var str []byte
+	var c byte
+	for iter.Error == nil {
+		c = iter.readByte()
+		if c == '"' {
+			return string(str)
+		}
+		if c == '\\' {
+			c = iter.readByte()
+			str = iter.readEscapedChar(c, str)
+		} else {
+			str = append(str, c)
+		}
+	}
+	iter.ReportError("readStringSlowPath", "unexpected end of input")
+	return
+}
+
+func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte {
+	switch c {
+	case 'u':
+		r := iter.readU4()
+		if utf16.IsSurrogate(r) {
+			c = iter.readByte()
+			if iter.Error != nil {
+				return nil
+			}
+			if c != '\\' {
+				iter.unreadByte()
+				str = appendRune(str, r)
+				return str
+			}
+			c = iter.readByte()
+			if iter.Error != nil {
+				return nil
+			}
+			if c != 'u' {
+				str = appendRune(str, r)
+				return iter.readEscapedChar(c, str)
+			}
+			r2 := iter.readU4()
+			if iter.Error != nil {
+				return nil
+			}
+			combined := utf16.DecodeRune(r, r2)
+			if combined == '\uFFFD' {
+				str = appendRune(str, r)
+				str = appendRune(str, r2)
+			} else {
+				str = appendRune(str, combined)
+			}
+		} else {
+			str = appendRune(str, r)
+		}
+	case '"':
+		str = append(str, '"')
+	case '\\':
+		str = append(str, '\\')
+	case '/':
+		str = append(str, '/')
+	case 'b':
+		str = append(str, '\b')
+	case 'f':
+		str = append(str, '\f')
+	case 'n':
+		str = append(str, '\n')
+	case 'r':
+		str = append(str, '\r')
+	case 't':
+		str = append(str, '\t')
+	default:
+		iter.ReportError("readEscapedChar",
+			`invalid escape char after \`)
+		return nil
+	}
+	return str
+}
+
+// ReadStringAsSlice read string from iterator without copying into string form.
+// The []byte can not be kept, as it will change after next iterator call.
+func (iter *Iterator) ReadStringAsSlice() (ret []byte) {
+	c := iter.nextToken()
+	if c == '"' {
+		for i := iter.head; i < iter.tail; i++ {
+			// require ascii string and no escape
+			// for: field name, base64, number
+			if iter.buf[i] == '"' {
+				// fast path: reuse the underlying buffer
+				ret = iter.buf[iter.head:i]
+				iter.head = i + 1
+				return ret
+			}
+		}
+		readLen := iter.tail - iter.head
+		copied := make([]byte, readLen, readLen*2)
+		copy(copied, iter.buf[iter.head:iter.tail])
+		iter.head = iter.tail
+		for iter.Error == nil {
+			c := iter.readByte()
+			if c == '"' {
+				return copied
+			}
+			copied = append(copied, c)
+		}
+		return copied
+	}
+	iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c}))
+	return
+}
+
+func (iter *Iterator) readU4() (ret rune) {
+	for i := 0; i < 4; i++ {
+		c := iter.readByte()
+		if iter.Error != nil {
+			return
+		}
+		if c >= '0' && c <= '9' {
+			ret = ret*16 + rune(c-'0')
+		} else if c >= 'a' && c <= 'f' {
+			ret = ret*16 + rune(c-'a'+10)
+		} 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}))
+			return
+		}
+	}
+	return ret
+}
+
+const (
+	t1 = 0x00 // 0000 0000
+	tx = 0x80 // 1000 0000
+	t2 = 0xC0 // 1100 0000
+	t3 = 0xE0 // 1110 0000
+	t4 = 0xF0 // 1111 0000
+	t5 = 0xF8 // 1111 1000
+
+	maskx = 0x3F // 0011 1111
+	mask2 = 0x1F // 0001 1111
+	mask3 = 0x0F // 0000 1111
+	mask4 = 0x07 // 0000 0111
+
+	rune1Max = 1<<7 - 1
+	rune2Max = 1<<11 - 1
+	rune3Max = 1<<16 - 1
+
+	surrogateMin = 0xD800
+	surrogateMax = 0xDFFF
+
+	maxRune   = '\U0010FFFF' // Maximum valid Unicode code point.
+	runeError = '\uFFFD'     // the "error" Rune or "Unicode replacement character"
+)
+
+func appendRune(p []byte, r rune) []byte {
+	// Negative values are erroneous. Making it unsigned addresses the problem.
+	switch i := uint32(r); {
+	case i <= rune1Max:
+		p = append(p, byte(r))
+		return p
+	case i <= rune2Max:
+		p = append(p, t2|byte(r>>6))
+		p = append(p, tx|byte(r)&maskx)
+		return p
+	case i > maxRune, surrogateMin <= i && i <= surrogateMax:
+		r = runeError
+		fallthrough
+	case i <= rune3Max:
+		p = append(p, t3|byte(r>>12))
+		p = append(p, tx|byte(r>>6)&maskx)
+		p = append(p, tx|byte(r)&maskx)
+		return p
+	default:
+		p = append(p, t4|byte(r>>18))
+		p = append(p, tx|byte(r>>12)&maskx)
+		p = append(p, tx|byte(r>>6)&maskx)
+		p = append(p, tx|byte(r)&maskx)
+		return p
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/jsoniter.go b/vendor/github.com/json-iterator/go/jsoniter.go
new file mode 100644
index 000000000..c2934f916
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/jsoniter.go
@@ -0,0 +1,18 @@
+// Package jsoniter implements encoding and decoding of JSON as defined in
+// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json.
+// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter
+// and variable type declarations (if any).
+// jsoniter interfaces gives 100% compatibility with code using standard lib.
+//
+// "JSON and Go"
+// (https://golang.org/doc/articles/json_and_go.html)
+// gives a description of how Marshal/Unmarshal operate
+// between arbitrary or predefined json objects and bytes,
+// and it applies to jsoniter.Marshal/Unmarshal as well.
+//
+// Besides, jsoniter.Iterator provides a different set of interfaces
+// iterating given bytes/string/reader
+// and yielding parsed elements one by one.
+// This set of interfaces reads input as required and gives
+// better performance.
+package jsoniter
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_array_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_array_test.go
new file mode 100644
index 000000000..56e3e12c0
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_array_test.go
@@ -0,0 +1,226 @@
+package misc_tests
+
+import (
+	"bytes"
+	"encoding/json"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_empty_array(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[]`)
+	cont := iter.ReadArray()
+	should.False(cont)
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[]`)
+	iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool {
+		should.FailNow("should not call")
+		return true
+	})
+}
+
+func Test_one_element(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1]`)
+	should.True(iter.ReadArray())
+	should.Equal(1, iter.ReadInt())
+	should.False(iter.ReadArray())
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[1]`)
+	iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool {
+		should.Equal(1, iter.ReadInt())
+		return true
+	})
+}
+
+func Test_two_elements(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1,2]`)
+	should.True(iter.ReadArray())
+	should.Equal(int64(1), iter.ReadInt64())
+	should.True(iter.ReadArray())
+	should.Equal(int64(2), iter.ReadInt64())
+	should.False(iter.ReadArray())
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[1,2]`)
+	should.Equal([]interface{}{float64(1), float64(2)}, iter.Read())
+}
+
+func Test_whitespace_in_head(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, ` [1]`)
+	cont := iter.ReadArray()
+	if cont != true {
+		t.FailNow()
+	}
+	if iter.ReadUint64() != 1 {
+		t.FailNow()
+	}
+}
+
+func Test_whitespace_after_array_start(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ 1]`)
+	cont := iter.ReadArray()
+	if cont != true {
+		t.FailNow()
+	}
+	if iter.ReadUint64() != 1 {
+		t.FailNow()
+	}
+}
+
+func Test_whitespace_before_array_end(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1 ]`)
+	cont := iter.ReadArray()
+	if cont != true {
+		t.FailNow()
+	}
+	if iter.ReadUint64() != 1 {
+		t.FailNow()
+	}
+	cont = iter.ReadArray()
+	if cont != false {
+		t.FailNow()
+	}
+}
+
+func Test_whitespace_before_comma(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1 ,2]`)
+	cont := iter.ReadArray()
+	if cont != true {
+		t.FailNow()
+	}
+	if iter.ReadUint64() != 1 {
+		t.FailNow()
+	}
+	cont = iter.ReadArray()
+	if cont != true {
+		t.FailNow()
+	}
+	if iter.ReadUint64() != 2 {
+		t.FailNow()
+	}
+	cont = iter.ReadArray()
+	if cont != false {
+		t.FailNow()
+	}
+}
+
+func Test_write_array(t *testing.T) {
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.Config{IndentionStep: 2}.Froze(), buf, 4096)
+	stream.WriteArrayStart()
+	stream.WriteInt(1)
+	stream.WriteMore()
+	stream.WriteInt(2)
+	stream.WriteArrayEnd()
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("[\n  1,\n  2\n]", buf.String())
+}
+
+func Test_write_val_array(t *testing.T) {
+	should := require.New(t)
+	val := []int{1, 2, 3}
+	str, err := jsoniter.MarshalToString(&val)
+	should.Nil(err)
+	should.Equal("[1,2,3]", str)
+}
+
+func Test_write_val_empty_array(t *testing.T) {
+	should := require.New(t)
+	val := []int{}
+	str, err := jsoniter.MarshalToString(val)
+	should.Nil(err)
+	should.Equal("[]", str)
+}
+
+func Test_write_array_of_interface_in_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field  []interface{}
+		Field2 string
+	}
+	val := TestObject{[]interface{}{1, 2}, ""}
+	str, err := jsoniter.MarshalToString(val)
+	should.Nil(err)
+	should.Contains(str, `"Field":[1,2]`)
+	should.Contains(str, `"Field2":""`)
+}
+
+func Test_encode_byte_array(t *testing.T) {
+	should := require.New(t)
+	bytes, err := json.Marshal([]byte{1, 2, 3})
+	should.Nil(err)
+	should.Equal(`"AQID"`, string(bytes))
+	bytes, err = jsoniter.Marshal([]byte{1, 2, 3})
+	should.Nil(err)
+	should.Equal(`"AQID"`, string(bytes))
+}
+
+func Test_decode_byte_array_from_base64(t *testing.T) {
+	should := require.New(t)
+	data := []byte{}
+	err := json.Unmarshal([]byte(`"AQID"`), &data)
+	should.Nil(err)
+	should.Equal([]byte{1, 2, 3}, data)
+	err = jsoniter.Unmarshal([]byte(`"AQID"`), &data)
+	should.Nil(err)
+	should.Equal([]byte{1, 2, 3}, data)
+}
+
+func Test_decode_byte_array_from_base64_with_newlines(t *testing.T) {
+	should := require.New(t)
+	data := []byte{}
+	err := json.Unmarshal([]byte(`"A\rQ\nID"`), &data)
+	should.Nil(err)
+	should.Equal([]byte{1, 2, 3}, data)
+	err = jsoniter.Unmarshal([]byte(`"A\rQ\nID"`), &data)
+	should.Nil(err)
+	should.Equal([]byte{1, 2, 3}, data)
+}
+
+func Test_decode_byte_array_from_array(t *testing.T) {
+	should := require.New(t)
+	data := []byte{}
+	err := json.Unmarshal([]byte(`[1,2,3]`), &data)
+	should.Nil(err)
+	should.Equal([]byte{1, 2, 3}, data)
+	err = jsoniter.Unmarshal([]byte(`[1,2,3]`), &data)
+	should.Nil(err)
+	should.Equal([]byte{1, 2, 3}, data)
+}
+
+func Test_decode_slice(t *testing.T) {
+	should := require.New(t)
+	slice := make([]string, 0, 5)
+	jsoniter.UnmarshalFromString(`["hello", "world"]`, &slice)
+	should.Equal([]string{"hello", "world"}, slice)
+}
+
+func Test_decode_large_slice(t *testing.T) {
+	should := require.New(t)
+	slice := make([]int, 0, 1)
+	jsoniter.UnmarshalFromString(`[1,2,3,4,5,6,7,8,9]`, &slice)
+	should.Equal([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, slice)
+}
+
+func Benchmark_jsoniter_array(b *testing.B) {
+	b.ReportAllocs()
+	input := []byte(`[1,2,3,4,5,6,7,8,9]`)
+	iter := jsoniter.ParseBytes(jsoniter.ConfigDefault, input)
+	b.ResetTimer()
+	for n := 0; n < b.N; n++ {
+		iter.ResetBytes(input)
+		for iter.ReadArray() {
+			iter.ReadUint64()
+		}
+	}
+}
+
+func Benchmark_json_array(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		result := []interface{}{}
+		json.Unmarshal([]byte(`[1,2,3]`), &result)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_bool_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_bool_test.go
new file mode 100644
index 000000000..8353d19b4
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_bool_test.go
@@ -0,0 +1,47 @@
+package misc_tests
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_true(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `true`)
+	should.True(iter.ReadBool())
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `true`)
+	should.Equal(true, iter.Read())
+}
+
+func Test_false(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `false`)
+	should.False(iter.ReadBool())
+}
+
+func Test_write_true_false(t *testing.T) {
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+	stream.WriteTrue()
+	stream.WriteFalse()
+	stream.WriteBool(false)
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("truefalsefalse", buf.String())
+}
+
+func Test_write_val_bool(t *testing.T) {
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+	stream.WriteVal(true)
+	should.Equal(stream.Buffered(), 4)
+	stream.Flush()
+	should.Equal(stream.Buffered(), 0)
+	should.Nil(stream.Error)
+	should.Equal("true", buf.String())
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_float_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_float_test.go
new file mode 100644
index 000000000..de7bc965e
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_float_test.go
@@ -0,0 +1,95 @@
+package misc_tests
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_read_big_float(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `12.3`)
+	val := iter.ReadBigFloat()
+	val64, _ := val.Float64()
+	should.Equal(12.3, val64)
+}
+
+func Test_read_big_int(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `92233720368547758079223372036854775807`)
+	val := iter.ReadBigInt()
+	should.NotNil(val)
+	should.Equal(`92233720368547758079223372036854775807`, val.String())
+}
+
+func Test_read_float_as_interface(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `12.3`)
+	should.Equal(float64(12.3), iter.Read())
+}
+
+func Test_wrap_float(t *testing.T) {
+	should := require.New(t)
+	str, err := jsoniter.MarshalToString(jsoniter.WrapFloat64(12.3))
+	should.Nil(err)
+	should.Equal("12.3", str)
+}
+
+func Test_read_float64_cursor(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, "[1.23456789\n,2,3]")
+	should.True(iter.ReadArray())
+	should.Equal(1.23456789, iter.Read())
+	should.True(iter.ReadArray())
+	should.Equal(float64(2), iter.Read())
+}
+
+func Test_read_float_scientific(t *testing.T) {
+	should := require.New(t)
+	var obj interface{}
+	should.NoError(jsoniter.UnmarshalFromString(`1e1`, &obj))
+	should.Equal(float64(10), obj)
+	should.NoError(json.Unmarshal([]byte(`1e1`), &obj))
+	should.Equal(float64(10), obj)
+	should.NoError(jsoniter.UnmarshalFromString(`1.0e1`, &obj))
+	should.Equal(float64(10), obj)
+	should.NoError(json.Unmarshal([]byte(`1.0e1`), &obj))
+	should.Equal(float64(10), obj)
+}
+
+func Test_lossy_float_marshal(t *testing.T) {
+	should := require.New(t)
+	api := jsoniter.Config{MarshalFloatWith6Digits: true}.Froze()
+	output, err := api.MarshalToString(float64(0.1234567))
+	should.Nil(err)
+	should.Equal("0.123457", output)
+	output, err = api.MarshalToString(float32(0.1234567))
+	should.Nil(err)
+	should.Equal("0.123457", output)
+}
+
+func Test_read_number(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `92233720368547758079223372036854775807`)
+	val := iter.ReadNumber()
+	should.Equal(`92233720368547758079223372036854775807`, string(val))
+}
+
+func Benchmark_jsoniter_float(b *testing.B) {
+	b.ReportAllocs()
+	input := []byte(`1.1123,`)
+	iter := jsoniter.NewIterator(jsoniter.ConfigDefault)
+	for n := 0; n < b.N; n++ {
+		iter.ResetBytes(input)
+		iter.ReadFloat64()
+	}
+}
+
+func Benchmark_json_float(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		result := float64(0)
+		json.Unmarshal([]byte(`1.1`), &result)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_int_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_int_test.go
new file mode 100644
index 000000000..a730f6986
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_int_test.go
@@ -0,0 +1,101 @@
+// +build go1.8
+
+package misc_tests
+
+import (
+	"bytes"
+	"encoding/json"
+	"io/ioutil"
+	"strconv"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_read_uint64_invalid(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, ",")
+	iter.ReadUint64()
+	should.NotNil(iter.Error)
+}
+
+func Test_read_int32_array(t *testing.T) {
+	should := require.New(t)
+	input := `[123,456,789]`
+	val := make([]int32, 0)
+	jsoniter.UnmarshalFromString(input, &val)
+	should.Equal(3, len(val))
+}
+
+func Test_read_int64_array(t *testing.T) {
+	should := require.New(t)
+	input := `[123,456,789]`
+	val := make([]int64, 0)
+	jsoniter.UnmarshalFromString(input, &val)
+	should.Equal(3, len(val))
+}
+
+func Test_wrap_int(t *testing.T) {
+	should := require.New(t)
+	str, err := jsoniter.MarshalToString(jsoniter.WrapInt64(100))
+	should.Nil(err)
+	should.Equal("100", str)
+}
+
+func Test_write_val_int(t *testing.T) {
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+	stream.WriteVal(1001)
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("1001", buf.String())
+}
+
+func Test_write_val_int_ptr(t *testing.T) {
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+	val := 1001
+	stream.WriteVal(&val)
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("1001", buf.String())
+}
+
+func Test_float_as_int(t *testing.T) {
+	should := require.New(t)
+	var i int
+	should.NotNil(jsoniter.Unmarshal([]byte(`1.1`), &i))
+}
+
+func Benchmark_jsoniter_encode_int(b *testing.B) {
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, ioutil.Discard, 64)
+	for n := 0; n < b.N; n++ {
+		stream.Reset(nil)
+		stream.WriteUint64(0xffffffff)
+	}
+}
+
+func Benchmark_itoa(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		strconv.FormatInt(0xffffffff, 10)
+	}
+}
+
+func Benchmark_jsoniter_int(b *testing.B) {
+	iter := jsoniter.NewIterator(jsoniter.ConfigDefault)
+	input := []byte(`100`)
+	for n := 0; n < b.N; n++ {
+		iter.ResetBytes(input)
+		iter.ReadInt64()
+	}
+}
+
+func Benchmark_json_int(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		result := int64(0)
+		json.Unmarshal([]byte(`-100`), &result)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_interface_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_interface_test.go
new file mode 100644
index 000000000..6ea75b57a
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_interface_test.go
@@ -0,0 +1,178 @@
+package misc_tests
+
+import (
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"io"
+	"testing"
+)
+
+func Test_nil_non_empty_interface(t *testing.T) {
+	type TestObject struct {
+		Field []io.Closer
+	}
+	should := require.New(t)
+	obj := TestObject{}
+	b := []byte(`{"Field":["AAA"]}`)
+	should.NotNil(json.Unmarshal(b, &obj))
+	should.NotNil(jsoniter.Unmarshal(b, &obj))
+}
+
+func Test_nil_out_null_interface(t *testing.T) {
+	type TestData struct {
+		Field interface{} `json:"field"`
+	}
+	should := require.New(t)
+
+	var boolVar bool
+	obj := TestData{
+		Field: &boolVar,
+	}
+
+	data1 := []byte(`{"field": true}`)
+
+	err := jsoniter.Unmarshal(data1, &obj)
+	should.NoError(err)
+	should.Equal(true, *(obj.Field.(*bool)))
+
+	data2 := []byte(`{"field": null}`)
+
+	err = jsoniter.Unmarshal(data2, &obj)
+	should.NoError(err)
+	should.Nil(obj.Field)
+
+	// Checking stdlib behavior matches.
+	obj2 := TestData{
+		Field: &boolVar,
+	}
+
+	err = json.Unmarshal(data1, &obj2)
+	should.NoError(err)
+	should.Equal(true, *(obj2.Field.(*bool)))
+
+	err = json.Unmarshal(data2, &obj2)
+	should.NoError(err)
+	should.Equal(nil, obj2.Field)
+}
+
+func Test_overwrite_interface_ptr_value_with_nil(t *testing.T) {
+	type Wrapper struct {
+		Payload interface{} `json:"payload,omitempty"`
+	}
+	type Payload struct {
+		Value int `json:"val,omitempty"`
+	}
+
+	should := require.New(t)
+
+	payload := &Payload{}
+	wrapper := &Wrapper{
+		Payload: &payload,
+	}
+
+	err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
+	should.NoError(err)
+	should.Equal(&payload, wrapper.Payload)
+	should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
+
+	err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
+	should.NoError(err)
+	should.Equal(&payload, wrapper.Payload)
+	should.Equal((*Payload)(nil), payload)
+
+	payload = &Payload{}
+	wrapper = &Wrapper{
+		Payload: &payload,
+	}
+
+	err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
+	should.Equal(nil, err)
+	should.Equal(&payload, wrapper.Payload)
+	should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
+
+	err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
+	should.NoError(err)
+	should.Equal(&payload, wrapper.Payload)
+	should.Equal((*Payload)(nil), payload)
+}
+
+func Test_overwrite_interface_value_with_nil(t *testing.T) {
+	type Wrapper struct {
+		Payload interface{} `json:"payload,omitempty"`
+	}
+	type Payload struct {
+		Value int `json:"val,omitempty"`
+	}
+
+	should := require.New(t)
+
+	payload := &Payload{}
+	wrapper := &Wrapper{
+		Payload: payload,
+	}
+
+	err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
+	should.NoError(err)
+	should.Equal(42, wrapper.Payload.(*Payload).Value)
+
+	err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
+	should.NoError(err)
+	should.Equal(nil, wrapper.Payload)
+	should.Equal(42, payload.Value)
+
+	payload = &Payload{}
+	wrapper = &Wrapper{
+		Payload: payload,
+	}
+
+	err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
+	should.Equal(nil, err)
+	should.Equal(42, wrapper.Payload.(*Payload).Value)
+
+	err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
+	should.Equal(nil, err)
+	should.Equal(nil, wrapper.Payload)
+	should.Equal(42, payload.Value)
+}
+
+func Test_unmarshal_into_nil(t *testing.T) {
+	type Payload struct {
+		Value int `json:"val,omitempty"`
+	}
+	type Wrapper struct {
+		Payload interface{} `json:"payload,omitempty"`
+	}
+
+	should := require.New(t)
+
+	var payload *Payload
+	wrapper := &Wrapper{
+		Payload: payload,
+	}
+
+	err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
+	should.NoError(err)
+	should.NotNil(wrapper.Payload)
+	should.Nil(payload)
+
+	err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
+	should.NoError(err)
+	should.Nil(wrapper.Payload)
+	should.Nil(payload)
+
+	payload = nil
+	wrapper = &Wrapper{
+		Payload: payload,
+	}
+
+	err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
+	should.NoError(err)
+	should.NotNil(wrapper.Payload)
+	should.Nil(payload)
+
+	err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
+	should.NoError(err)
+	should.Nil(wrapper.Payload)
+	should.Nil(payload)
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_iterator_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_iterator_test.go
new file mode 100644
index 000000000..d75d01a51
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_iterator_test.go
@@ -0,0 +1,67 @@
+package misc_tests
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"strconv"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_bad_case(t *testing.T) {
+	// field := *(*string)(unsafe.Pointer(&str))
+	// caused this issue
+	iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(`{"Info":{"InfoHash":"4lzhP/fwlVLRgalC31YbfBSiqwo=","InfoHashstr":"E25CE13FF7F09552D181A942DF561B7C14A2AB0A","AnnounceList":["http://tracker.nwps.ws:6969/announce","http://tracker.nwps.ws:6969/announce","http://tracker.winglai.com/announce","http://fr33dom.h33t.com:3310/announce","http://exodus.desync.com:6969/announce","http://torrent.gresille.org/announce","http://tracker.trackerfix.com/announce","udp://tracker.btzoo.eu:80/announce","http://tracker.windsormetalbattery.com/announce","udp://10.rarbg.me:80/announce","udp://ipv4.tracker.harry.lu:80/announce","udp://tracker.ilibr.org:6969/announce","udp://tracker.zond.org:80/announce","http://torrent-tracker.ru/announce.php","http://bigfoot1942.sektori.org:6969/announce","http://tracker.best-torrents.net:6969/announce","http://announce.torrentsmd.com:6969/announce","udp://tracker.token.ro:80/announce","udp://tracker.coppersurfer.tk:80","http://tracker.thepiratebay.org/announce","udp://9.rarbg.com:2710/announce","udp://open.demonii.com:1337/announce","udp://tracker.ccc.de:80/announce","udp://tracker.istole.it:80/announce","udp://tracker.publicbt.com:80/announce","udp://tracker.openbittorrent.com:80/announce","udp://tracker.istole.it:80/announce","http://tracker.istole.it/announce","udp://tracker.publicbt.com:80/announce","http://tracker.publicbt.com/announce","udp://open.demonii.com:1337/announce"],"Length":2434793890,"PieceSize":524288,"PieceNum":4645},"InfoHashstr":"E25CE13FF7F09552D181A942DF561B7C14A2AB0A","SectionNum":32,"PieceNum":4645,"PieceSize":16384,"Finished":false,"SparseSize":104857600,"Bit":[{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}]}`), 4096)
+	count := 0
+	for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
+		if field == "Bit" {
+			for iter.ReadArray() {
+				for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
+					if field == "Bit" {
+						iter.ReadStringAsSlice()
+					} else {
+						if field != "Size" && field != "EndIndex" && field != "EndMask" && field != "Good" && field != "Flush" {
+							t.Fatal(field)
+						}
+						iter.Skip()
+					}
+				}
+				count++
+			}
+		} else {
+			iter.Skip()
+		}
+	}
+	if count != 32 {
+		t.Fatal(count)
+	}
+}
+
+func Test_iterator_use_number(t *testing.T) {
+	// Test UseNumber with iterator Read()
+	inputs := []string{`2147483647`, `-2147483648`}
+	for _, input := range inputs {
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.Config{UseNumber: true}.Froze(), input)
+			expected := json.Number(input)
+			should.Equal(expected, iter.Read())
+		})
+	}
+}
+
+func Test_iterator_without_number(t *testing.T) {
+	inputs := []string{`2147483647`, `-2147483648`}
+	for _, input := range inputs {
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
+			expected, err := strconv.ParseInt(input, 10, 32)
+			should.Nil(err)
+			should.Equal(float64(expected), iter.Read())
+		})
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_map_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_map_test.go
new file mode 100644
index 000000000..b0dde94cf
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_map_test.go
@@ -0,0 +1,44 @@
+package misc_tests
+
+import (
+	"encoding/json"
+	"math/big"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"strings"
+)
+
+func Test_decode_TextMarshaler_key_map(t *testing.T) {
+	should := require.New(t)
+	var val map[*big.Float]string
+	should.Nil(jsoniter.UnmarshalFromString(`{"1":"2"}`, &val))
+	str, err := jsoniter.MarshalToString(val)
+	should.Nil(err)
+	should.Equal(`{"1":"2"}`, str)
+}
+
+func Test_read_map_with_reader(t *testing.T) {
+	should := require.New(t)
+	input := `{"branch":"beta","change_log":"add the rows{10}","channel":"fros","create_time":"2017-06-13 16:39:08","firmware_list":"","md5":"80dee2bf7305bcf179582088e29fd7b9","note":{"CoreServices":{"md5":"d26975c0a8c7369f70ed699f2855cc2e","package_name":"CoreServices","version_code":"76","version_name":"1.0.76"},"FrDaemon":{"md5":"6b1f0626673200bc2157422cd2103f5d","package_name":"FrDaemon","version_code":"390","version_name":"1.0.390"},"FrGallery":{"md5":"90d767f0f31bcd3c1d27281ec979ba65","package_name":"FrGallery","version_code":"349","version_name":"1.0.349"},"FrLocal":{"md5":"f15a215b2c070a80a01f07bde4f219eb","package_name":"FrLocal","version_code":"791","version_name":"1.0.791"}},"pack_region_urls":{"CN":"https://s3.cn-north-1.amazonaws.com.cn/xxx-os/ttt_xxx_android_1.5.3.344.393.zip","default":"http://192.168.8.78/ttt_xxx_android_1.5.3.344.393.zip","local":"http://192.168.8.78/ttt_xxx_android_1.5.3.344.393.zip"},"pack_version":"1.5.3.344.393","pack_version_code":393,"region":"all","release_flag":0,"revision":62,"size":38966875,"status":3}`
+	reader := strings.NewReader(input)
+	decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(reader)
+	m1 := map[string]interface{}{}
+	should.Nil(decoder.Decode(&m1))
+	m2 := map[string]interface{}{}
+	should.Nil(json.Unmarshal([]byte(input), &m2))
+	should.Equal(m2, m1)
+	should.Equal("1.0.76", m1["note"].(map[string]interface{})["CoreServices"].(map[string]interface{})["version_name"])
+}
+
+func Test_map_eface_of_eface(t *testing.T) {
+	should := require.New(t)
+	json := jsoniter.ConfigCompatibleWithStandardLibrary
+	output, err := json.MarshalToString(map[interface{}]interface{}{
+		"1": 2,
+		3:   "4",
+	})
+	should.NoError(err)
+	should.Equal(`{"1":2,"3":"4"}`, output)
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_nested_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_nested_test.go
new file mode 100644
index 000000000..1e4994a13
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_nested_test.go
@@ -0,0 +1,89 @@
+package misc_tests
+
+import (
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"reflect"
+	"testing"
+)
+
+type Level1 struct {
+	Hello []Level2
+}
+
+type Level2 struct {
+	World string
+}
+
+func Test_nested(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"hello": [{"world": "value1"}, {"world": "value2"}]}`)
+	l1 := Level1{}
+	for l1Field := iter.ReadObject(); l1Field != ""; l1Field = iter.ReadObject() {
+		switch l1Field {
+		case "hello":
+			l2Array := []Level2{}
+			for iter.ReadArray() {
+				l2 := Level2{}
+				for l2Field := iter.ReadObject(); l2Field != ""; l2Field = iter.ReadObject() {
+					switch l2Field {
+					case "world":
+						l2.World = iter.ReadString()
+					default:
+						iter.ReportError("bind l2", "unexpected field: "+l2Field)
+					}
+				}
+				l2Array = append(l2Array, l2)
+			}
+			l1.Hello = l2Array
+		default:
+			iter.ReportError("bind l1", "unexpected field: "+l1Field)
+		}
+	}
+	if !reflect.DeepEqual(l1, Level1{
+		Hello: []Level2{
+			{World: "value1"},
+			{World: "value2"},
+		},
+	}) {
+		t.Fatal(l1)
+	}
+}
+
+func Benchmark_jsoniter_nested(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"hello": [{"world": "value1"}, {"world": "value2"}]}`)
+		l1 := Level1{}
+		for l1Field := iter.ReadObject(); l1Field != ""; l1Field = iter.ReadObject() {
+			switch l1Field {
+			case "hello":
+				l1.Hello = readLevel1Hello(iter)
+			default:
+				iter.Skip()
+			}
+		}
+	}
+}
+
+func readLevel1Hello(iter *jsoniter.Iterator) []Level2 {
+	l2Array := make([]Level2, 0, 2)
+	for iter.ReadArray() {
+		l2 := Level2{}
+		for l2Field := iter.ReadObject(); l2Field != ""; l2Field = iter.ReadObject() {
+			switch l2Field {
+			case "world":
+				l2.World = iter.ReadString()
+			default:
+				iter.Skip()
+			}
+		}
+		l2Array = append(l2Array, l2)
+	}
+	return l2Array
+}
+
+func Benchmark_json_nested(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		l1 := Level1{}
+		json.Unmarshal([]byte(`{"hello": [{"world": "value1"}, {"world": "value2"}]}`), &l1)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_null_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_null_test.go
new file mode 100644
index 000000000..4fd2a2c13
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_null_test.go
@@ -0,0 +1,81 @@
+package misc_tests
+
+import (
+	"bytes"
+	"io"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_read_null(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `null`)
+	should.True(iter.ReadNil())
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `null`)
+	should.Nil(iter.Read())
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `navy`)
+	iter.Read()
+	should.True(iter.Error != nil && iter.Error != io.EOF)
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `navy`)
+	iter.ReadNil()
+	should.True(iter.Error != nil && iter.Error != io.EOF)
+}
+
+func Test_write_null(t *testing.T) {
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+	stream.WriteNil()
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("null", buf.String())
+}
+
+func Test_decode_null_object_field(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`)
+	iter.ReadArray()
+	if iter.ReadObject() != "" {
+		t.FailNow()
+	}
+	iter.ReadArray()
+	if iter.ReadString() != "a" {
+		t.FailNow()
+	}
+	type TestObject struct {
+		Field string
+	}
+	objs := []TestObject{}
+	should.Nil(jsoniter.UnmarshalFromString("[null]", &objs))
+	should.Len(objs, 1)
+}
+
+func Test_decode_null_array_element(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`)
+	should.True(iter.ReadArray())
+	should.True(iter.ReadNil())
+	should.True(iter.ReadArray())
+	should.Equal("a", iter.ReadString())
+}
+
+func Test_decode_null_string(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`)
+	should.True(iter.ReadArray())
+	should.Equal("", iter.ReadString())
+	should.True(iter.ReadArray())
+	should.Equal("a", iter.ReadString())
+}
+
+func Test_decode_null_skip(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	if iter.ReadString() != "a" {
+		t.FailNow()
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_object_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_object_test.go
new file mode 100644
index 000000000..e44b66f05
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_object_test.go
@@ -0,0 +1,149 @@
+package misc_tests
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"strings"
+	"time"
+)
+
+func Test_empty_object(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{}`)
+	field := iter.ReadObject()
+	should.Equal("", field)
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{}`)
+	iter.ReadObjectCB(func(iter *jsoniter.Iterator, field string) bool {
+		should.FailNow("should not call")
+		return true
+	})
+}
+
+func Test_one_field(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"a": "stream"}`)
+	field := iter.ReadObject()
+	should.Equal("a", field)
+	value := iter.ReadString()
+	should.Equal("stream", value)
+	field = iter.ReadObject()
+	should.Equal("", field)
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{"a": "stream"}`)
+	should.True(iter.ReadObjectCB(func(iter *jsoniter.Iterator, field string) bool {
+		should.Equal("a", field)
+		iter.Skip()
+		return true
+	}))
+
+}
+
+func Test_two_field(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{ "a": "stream" , "c": "d" }`)
+	field := iter.ReadObject()
+	should.Equal("a", field)
+	value := iter.ReadString()
+	should.Equal("stream", value)
+	field = iter.ReadObject()
+	should.Equal("c", field)
+	value = iter.ReadString()
+	should.Equal("d", value)
+	field = iter.ReadObject()
+	should.Equal("", field)
+	iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{"field1": "1", "field2": 2}`)
+	for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
+		switch field {
+		case "field1":
+			iter.ReadString()
+		case "field2":
+			iter.ReadInt64()
+		default:
+			iter.ReportError("bind object", "unexpected field")
+		}
+	}
+}
+
+func Test_write_object(t *testing.T) {
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.Config{IndentionStep: 2}.Froze(), buf, 4096)
+	stream.WriteObjectStart()
+	stream.WriteObjectField("hello")
+	stream.WriteInt(1)
+	stream.WriteMore()
+	stream.WriteObjectField("world")
+	stream.WriteInt(2)
+	stream.WriteObjectEnd()
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("{\n  \"hello\": 1,\n  \"world\": 2\n}", buf.String())
+}
+
+func Test_reader_and_load_more(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		CreatedAt time.Time
+	}
+	reader := strings.NewReader(`
+{
+	"agency": null,
+	"candidateId": 0,
+	"candidate": "Blah Blah",
+	"bookingId": 0,
+	"shiftId": 1,
+	"shiftTypeId": 0,
+	"shift": "Standard",
+	"bonus": 0,
+	"bonusNI": 0,
+	"days": [],
+	"totalHours": 27,
+	"expenses": [],
+	"weekEndingDateSystem": "2016-10-09",
+	"weekEndingDateClient": "2016-10-09",
+	"submittedAt": null,
+	"submittedById": null,
+	"approvedAt": "2016-10-10T18:38:04Z",
+	"approvedById": 0,
+	"authorisedAt": "2016-10-10T18:38:04Z",
+	"authorisedById": 0,
+	"invoicedAt": "2016-10-10T20:00:00Z",
+	"revokedAt": null,
+	"revokedById": null,
+	"revokeReason": null,
+	"rejectedAt": null,
+	"rejectedById": null,
+	"rejectReasonCode": null,
+	"rejectReason": null,
+	"createdAt": "2016-10-03T00:00:00Z",
+	"updatedAt": "2016-11-09T10:26:13Z",
+	"updatedById": null,
+	"overrides": [],
+	"bookingApproverId": null,
+	"bookingApprover": null,
+	"status": "approved"
+}
+	`)
+	decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(reader)
+	obj := TestObject{}
+	should.Nil(decoder.Decode(&obj))
+}
+
+func Test_unmarshal_into_existing_value(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 int
+		Field2 interface{}
+	}
+	var obj TestObject
+	m := map[string]interface{}{}
+	obj.Field2 = &m
+	cfg := jsoniter.Config{UseNumber: true}.Froze()
+	err := cfg.Unmarshal([]byte(`{"Field1":1,"Field2":{"k":"v"}}`), &obj)
+	should.NoError(err)
+	should.Equal(map[string]interface{}{
+		"k": "v",
+	}, m)
+}
diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_raw_message_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_raw_message_test.go
new file mode 100644
index 000000000..9af7cd73b
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_raw_message_test.go
@@ -0,0 +1,68 @@
+package misc_tests
+
+import (
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"strings"
+	"testing"
+)
+
+func Test_jsoniter_RawMessage(t *testing.T) {
+	should := require.New(t)
+	var data jsoniter.RawMessage
+	should.Nil(jsoniter.Unmarshal([]byte(`[1,2,3]`), &data))
+	should.Equal(`[1,2,3]`, string(data))
+	str, err := jsoniter.MarshalToString(data)
+	should.Nil(err)
+	should.Equal(`[1,2,3]`, str)
+}
+
+func Test_encode_map_of_jsoniter_raw_message(t *testing.T) {
+	should := require.New(t)
+	type RawMap map[string]*jsoniter.RawMessage
+	value := jsoniter.RawMessage("[]")
+	rawMap := RawMap{"hello": &value}
+	output, err := jsoniter.MarshalToString(rawMap)
+	should.Nil(err)
+	should.Equal(`{"hello":[]}`, output)
+}
+
+func Test_marshal_invalid_json_raw_message(t *testing.T) {
+	type A struct {
+		Raw json.RawMessage `json:"raw"`
+	}
+	message := []byte(`{}`)
+
+	a := A{}
+	should := require.New(t)
+	should.Nil(jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(message, &a))
+	aout, aouterr := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&a)
+	should.Equal(`{"raw":null}`, string(aout))
+	should.Nil(aouterr)
+}
+
+func Test_raw_message_memory_not_copied_issue(t *testing.T) {
+	jsonStream := `{"name":"xxxxx","bundle_id":"com.zonst.majiang","app_platform":"ios","app_category":"100103", "budget_day":1000,"bidding_min":1,"bidding_max":2,"bidding_type":"CPM", "freq":{"open":true,"type":"day","num":100},"speed":1, "targeting":{"vendor":{"open":true,"list":["zonst"]}, "geo_code":{"open":true,"list":["156110100"]},"app_category":{"open":true,"list":["100101"]}, "day_parting":{"open":true,"list":["100409","100410"]},"device_type":{"open":true,"list":["ipad"]}, "os_version":{"open":true,"list":[10]},"carrier":{"open":true,"list":["mobile"]}, "network":{"open":true,"list":["4G"]}},"url":{"tracking_imp_url":"http://www.baidu.com", "tracking_clk_url":"http://www.baidu.com","jump_url":"http://www.baidu.com","deep_link_url":"http://www.baidu.com"}}`
+	type IteratorObject struct {
+		Name        *string              `json:"name"`
+		BundleId    *string              `json:"bundle_id"`
+		AppCategory *string              `json:"app_category"`
+		AppPlatform *string              `json:"app_platform"`
+		BudgetDay   *float32             `json:"budget_day"`
+		BiddingMax  *float32             `json:"bidding_max"`
+		BiddingMin  *float32             `json:"bidding_min"`
+		BiddingType *string              `json:"bidding_type"`
+		Freq        *jsoniter.RawMessage `json:"freq"`
+		Targeting   *jsoniter.RawMessage `json:"targeting"`
+		Url         *jsoniter.RawMessage `json:"url"`
+		Speed       *int                 `json:"speed" db:"speed"`
+	}
+
+	obj := &IteratorObject{}
+	decoder := jsoniter.NewDecoder(strings.NewReader(jsonStream))
+	err := decoder.Decode(obj)
+	should := require.New(t)
+	should.Nil(err)
+	should.Equal(`{"open":true,"type":"day","num":100}`, string(*obj.Freq))
+}
diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/pool.go
new file mode 100644
index 000000000..e2389b56c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/pool.go
@@ -0,0 +1,42 @@
+package jsoniter
+
+import (
+	"io"
+)
+
+// IteratorPool a thread safe pool of iterators with same configuration
+type IteratorPool interface {
+	BorrowIterator(data []byte) *Iterator
+	ReturnIterator(iter *Iterator)
+}
+
+// StreamPool a thread safe pool of streams with same configuration
+type StreamPool interface {
+	BorrowStream(writer io.Writer) *Stream
+	ReturnStream(stream *Stream)
+}
+
+func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream {
+	stream := cfg.streamPool.Get().(*Stream)
+	stream.Reset(writer)
+	return stream
+}
+
+func (cfg *frozenConfig) ReturnStream(stream *Stream) {
+	stream.out = nil
+	stream.Error = nil
+	stream.Attachment = nil
+	cfg.streamPool.Put(stream)
+}
+
+func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator {
+	iter := cfg.iteratorPool.Get().(*Iterator)
+	iter.ResetBytes(data)
+	return iter
+}
+
+func (cfg *frozenConfig) ReturnIterator(iter *Iterator) {
+	iter.Error = nil
+	iter.Attachment = nil
+	cfg.iteratorPool.Put(iter)
+}
diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go
new file mode 100644
index 000000000..4459e203f
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect.go
@@ -0,0 +1,332 @@
+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
new file mode 100644
index 000000000..13a0b7b08
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_array.go
@@ -0,0 +1,104 @@
+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
new file mode 100644
index 000000000..8b6bc8b43
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_dynamic.go
@@ -0,0 +1,70 @@
+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_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go
new file mode 100644
index 000000000..04f68756b
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_extension.go
@@ -0,0 +1,483 @@
+package jsoniter
+
+import (
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"reflect"
+	"sort"
+	"strings"
+	"unicode"
+	"unsafe"
+)
+
+var typeDecoders = map[string]ValDecoder{}
+var fieldDecoders = map[string]ValDecoder{}
+var typeEncoders = map[string]ValEncoder{}
+var fieldEncoders = map[string]ValEncoder{}
+var extensions = []Extension{}
+
+// StructDescriptor describe how should we encode/decode the struct
+type StructDescriptor struct {
+	Type   reflect2.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 {
+			return binding
+		}
+	}
+	return nil
+}
+
+// Binding describe how should we encode/decode the struct field
+type Binding struct {
+	levels    []int
+	Field     reflect2.StructField
+	FromNames []string
+	ToNames   []string
+	Encoder   ValEncoder
+	Decoder   ValDecoder
+}
+
+// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder.
+// 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
+}
+
+// DummyExtension embed this type get dummy implementation for all methods of Extension
+type DummyExtension struct {
+}
+
+// UpdateStructDescriptor No-op
+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 {
+	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 {
+	return nil
+}
+
+// DecorateDecoder No-op
+func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
+	return decoder
+}
+
+// DecorateEncoder No-op
+func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
+	return encoder
+}
+
+type funcDecoder struct {
+	fun DecoderFunc
+}
+
+func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.fun(ptr, iter)
+}
+
+type funcEncoder struct {
+	fun         EncoderFunc
+	isEmptyFunc func(ptr unsafe.Pointer) bool
+}
+
+func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.fun(ptr, stream)
+}
+
+func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	if encoder.isEmptyFunc == nil {
+		return false
+	}
+	return encoder.isEmptyFunc(ptr)
+}
+
+// DecoderFunc the function form of TypeDecoder
+type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
+
+// EncoderFunc the function form of TypeEncoder
+type EncoderFunc func(ptr unsafe.Pointer, stream *Stream)
+
+// RegisterTypeDecoderFunc register TypeDecoder for a type with function
+func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
+	typeDecoders[typ] = &funcDecoder{fun}
+}
+
+// RegisterTypeDecoder register TypeDecoder for a typ
+func RegisterTypeDecoder(typ string, decoder ValDecoder) {
+	typeDecoders[typ] = decoder
+}
+
+// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function
+func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) {
+	RegisterFieldDecoder(typ, field, &funcDecoder{fun})
+}
+
+// RegisterFieldDecoder register TypeDecoder for a struct field
+func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) {
+	fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder
+}
+
+// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function
+func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
+	typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc}
+}
+
+// RegisterTypeEncoder register TypeEncoder for a type
+func RegisterTypeEncoder(typ string, encoder ValEncoder) {
+	typeEncoders[typ] = encoder
+}
+
+// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function
+func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
+	RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc})
+}
+
+// RegisterFieldEncoder register TypeEncoder for a struct field
+func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {
+	fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder
+}
+
+// RegisterExtension register extension
+func RegisterExtension(extension Extension) {
+	extensions = append(extensions, extension)
+}
+
+func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
+	decoder := _getTypeDecoderFromExtension(ctx, 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 {
+	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]
+	if decoder != nil {
+		return decoder
+	}
+	if typ.Kind() == reflect.Ptr {
+		ptrType := typ.(*reflect2.UnsafePtrType)
+		decoder := typeDecoders[ptrType.Elem().String()]
+		if decoder != nil {
+			return &OptionalDecoder{ptrType.Elem(), decoder}
+		}
+	}
+	return nil
+}
+
+func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
+	encoder := _getTypeEncoderFromExtension(ctx, 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 {
+	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]
+	if encoder != nil {
+		return encoder
+	}
+	if typ.Kind() == reflect.Ptr {
+		typePtr := typ.(*reflect2.UnsafePtrType)
+		encoder := typeEncoders[typePtr.Elem().String()]
+		if encoder != nil {
+			return &OptionalEncoder{encoder}
+		}
+	}
+	return nil
+}
+
+func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
+	structType := typ.(*reflect2.UnsafeStructType)
+	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
+		}
+		tagParts := strings.Split(tag, ",")
+		if tag == "-" {
+			continue
+		}
+		if field.Anonymous() && (tag == "" || tagParts[0] == "") {
+			if field.Type().Kind() == reflect.Struct {
+				structDescriptor := describeStruct(ctx, field.Type())
+				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}
+					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
+				}
+			}
+		}
+		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())
+		}
+		encoder := fieldEncoders[fieldCacheKey]
+		if encoder == nil {
+			encoder = encoderOfType(ctx.append(field.Name()), field.Type())
+		}
+		binding := &Binding{
+			Field:     field,
+			FromNames: fieldNames,
+			ToNames:   fieldNames,
+			Decoder:   decoder,
+			Encoder:   encoder,
+		}
+		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 {
+	structDescriptor := &StructDescriptor{
+		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)
+	// merge normal & embedded bindings & sort with original order
+	allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))
+	sort.Sort(allBindings)
+	structDescriptor.Fields = allBindings
+	return structDescriptor
+}
+
+type sortableBindings []*Binding
+
+func (bindings sortableBindings) Len() int {
+	return len(bindings)
+}
+
+func (bindings sortableBindings) Less(i, j int) bool {
+	left := bindings[i].levels
+	right := bindings[j].levels
+	k := 0
+	for {
+		if left[k] < right[k] {
+			return true
+		} else if left[k] > right[k] {
+			return false
+		}
+		k++
+	}
+}
+
+func (bindings sortableBindings) Swap(i, j int) {
+	bindings[i], bindings[j] = bindings[j], bindings[i]
+}
+
+func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) {
+	for _, binding := range structDescriptor.Fields {
+		shouldOmitEmpty := false
+		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 {
+					binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg}
+					binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg}
+				} else {
+					binding.Decoder = &stringModeNumberDecoder{binding.Decoder}
+					binding.Encoder = &stringModeNumberEncoder{binding.Encoder}
+				}
+			}
+		}
+		binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder}
+		binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty}
+	}
+}
+
+func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string {
+	// ignore?
+	if wholeTag == "-" {
+		return []string{}
+	}
+	// rename?
+	var fieldNames []string
+	if tagProvidedFieldName == "" {
+		fieldNames = []string{originalFieldName}
+	} else {
+		fieldNames = []string{tagProvidedFieldName}
+	}
+	// private?
+	isNotExported := unicode.IsLower(rune(originalFieldName[0]))
+	if isNotExported {
+		fieldNames = []string{}
+	}
+	return fieldNames
+}
diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go
new file mode 100644
index 000000000..98d45c1ec
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_json_number.go
@@ -0,0 +1,112 @@
+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
new file mode 100644
index 000000000..f2619936c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go
@@ -0,0 +1,60 @@
+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
new file mode 100644
index 000000000..547b4421e
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_map.go
@@ -0,0 +1,338 @@
+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(unmarshalerType) {
+			return &referenceDecoder{
+				&unmarshalerDecoder{
+					valType: ptrType,
+				},
+			}
+		}
+		if typ.Implements(unmarshalerType) {
+			return &unmarshalerDecoder{
+				valType: typ,
+			}
+		}
+		if ptrType.Implements(textUnmarshalerType) {
+			return &referenceDecoder{
+				&textUnmarshalerDecoder{
+					valType: ptrType,
+				},
+			}
+		}
+		if typ.Implements(textUnmarshalerType) {
+			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
new file mode 100644
index 000000000..58ac959ad
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_marshaler.go
@@ -0,0 +1,218 @@
+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
new file mode 100644
index 000000000..9042eb0cb
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_native.go
@@ -0,0 +1,451 @@
+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
new file mode 100644
index 000000000..43ec71d6d
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_optional.go
@@ -0,0 +1,133 @@
+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
new file mode 100644
index 000000000..9441d79df
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_slice.go
@@ -0,0 +1,99 @@
+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/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go
new file mode 100644
index 000000000..355d2d116
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go
@@ -0,0 +1,1048 @@
+package jsoniter
+
+import (
+	"fmt"
+	"io"
+	"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{}{
+		0: {},
+	}
+
+	switch len(fields) {
+	case 0:
+		return &skipObjectDecoder{typ}
+	case 1:
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}
+		}
+	case 2:
+		var fieldHash1 int64
+		var fieldHash2 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldHash1 == 0 {
+				fieldHash1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else {
+				fieldHash2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			}
+		}
+		return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}
+	case 3:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			}
+		}
+		return &threeFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3}
+	case 4:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			}
+		}
+		return &fourFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4}
+	case 5:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		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())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			}
+		}
+		return &fiveFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5}
+	case 6:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldName6 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			}
+		}
+		return &sixFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6}
+	case 7:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldName6 int64
+		var fieldName7 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			}
+		}
+		return &sevenFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7}
+	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 fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		var fieldDecoder8 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else if fieldName7 == 0 {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			} else {
+				fieldName8 = fieldHash
+				fieldDecoder8 = fieldDecoder
+			}
+		}
+		return &eightFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7,
+			fieldName8, fieldDecoder8}
+	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 fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		var fieldDecoder8 *structFieldDecoder
+		var fieldDecoder9 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else if fieldName7 == 0 {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			} else if fieldName8 == 0 {
+				fieldName8 = fieldHash
+				fieldDecoder8 = fieldDecoder
+			} else {
+				fieldName9 = fieldHash
+				fieldDecoder9 = fieldDecoder
+			}
+		}
+		return &nineFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7,
+			fieldName8, fieldDecoder8,
+			fieldName9, fieldDecoder9}
+	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 fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		var fieldDecoder8 *structFieldDecoder
+		var fieldDecoder9 *structFieldDecoder
+		var fieldDecoder10 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else if fieldName7 == 0 {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			} else if fieldName8 == 0 {
+				fieldName8 = fieldHash
+				fieldDecoder8 = fieldDecoder
+			} else if fieldName9 == 0 {
+				fieldName9 = fieldHash
+				fieldDecoder9 = fieldDecoder
+			} else {
+				fieldName10 = fieldHash
+				fieldDecoder10 = fieldDecoder
+			}
+		}
+		return &tenFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7,
+			fieldName8, fieldDecoder8,
+			fieldName9, fieldDecoder9,
+			fieldName10, fieldDecoder10}
+	}
+	return &generalStructDecoder{typ, fields, false}
+}
+
+type generalStructDecoder struct {
+	typ                   reflect2.Type
+	fields                map[string]*structFieldDecoder
+	disallowUnknownFields bool
+}
+
+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)]
+		}
+	} else {
+		field = iter.ReadString()
+		fieldDecoder = decoder.fields[field]
+		if fieldDecoder == nil && !iter.cfg.caseSensitive {
+			fieldDecoder = decoder.fields[strings.ToLower(field)]
+		}
+	}
+	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}))
+		}
+		iter.Skip()
+		return
+	}
+	c := iter.nextToken()
+	if c != ':' {
+		iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+	}
+	fieldDecoder.Decode(ptr, iter)
+}
+
+type skipObjectDecoder struct {
+	typ reflect2.Type
+}
+
+func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	valueType := iter.WhatIsNext()
+	if valueType != ObjectValue && valueType != NilValue {
+		iter.ReportError("skipObjectDecoder", "expect object or null")
+		return
+	}
+	iter.Skip()
+}
+
+type oneFieldStructDecoder struct {
+	typ          reflect2.Type
+	fieldHash    int64
+	fieldDecoder *structFieldDecoder
+}
+
+func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		if iter.readFieldHash() == decoder.fieldHash {
+			decoder.fieldDecoder.Decode(ptr, iter)
+		} else {
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type twoFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+}
+
+func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type threeFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+}
+
+func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type fourFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+}
+
+func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type fiveFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+}
+
+func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type sixFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+}
+
+func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type sevenFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+	fieldHash7    int64
+	fieldDecoder7 *structFieldDecoder
+}
+
+func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type eightFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+	fieldHash7    int64
+	fieldDecoder7 *structFieldDecoder
+	fieldHash8    int64
+	fieldDecoder8 *structFieldDecoder
+}
+
+func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		case decoder.fieldHash8:
+			decoder.fieldDecoder8.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type nineFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+	fieldHash7    int64
+	fieldDecoder7 *structFieldDecoder
+	fieldHash8    int64
+	fieldDecoder8 *structFieldDecoder
+	fieldHash9    int64
+	fieldDecoder9 *structFieldDecoder
+}
+
+func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		case decoder.fieldHash8:
+			decoder.fieldDecoder8.Decode(ptr, iter)
+		case decoder.fieldHash9:
+			decoder.fieldDecoder9.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type tenFieldsStructDecoder struct {
+	typ            reflect2.Type
+	fieldHash1     int64
+	fieldDecoder1  *structFieldDecoder
+	fieldHash2     int64
+	fieldDecoder2  *structFieldDecoder
+	fieldHash3     int64
+	fieldDecoder3  *structFieldDecoder
+	fieldHash4     int64
+	fieldDecoder4  *structFieldDecoder
+	fieldHash5     int64
+	fieldDecoder5  *structFieldDecoder
+	fieldHash6     int64
+	fieldDecoder6  *structFieldDecoder
+	fieldHash7     int64
+	fieldDecoder7  *structFieldDecoder
+	fieldHash8     int64
+	fieldDecoder8  *structFieldDecoder
+	fieldHash9     int64
+	fieldDecoder9  *structFieldDecoder
+	fieldHash10    int64
+	fieldDecoder10 *structFieldDecoder
+}
+
+func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		case decoder.fieldHash8:
+			decoder.fieldDecoder8.Decode(ptr, iter)
+		case decoder.fieldHash9:
+			decoder.fieldDecoder9.Decode(ptr, iter)
+		case decoder.fieldHash10:
+			decoder.fieldDecoder10.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type structFieldDecoder struct {
+	field        reflect2.StructField
+	fieldDecoder ValDecoder
+}
+
+func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	fieldPtr := decoder.field.UnsafeGet(ptr)
+	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
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go
new file mode 100644
index 000000000..d0759cf64
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go
@@ -0,0 +1,210 @@
+package jsoniter
+
+import (
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"io"
+	"reflect"
+	"unsafe"
+)
+
+func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
+	type bindingTo struct {
+		binding *Binding
+		toName  string
+		ignored bool
+	}
+	orderedBindings := []*bindingTo{}
+	structDescriptor := describeStruct(ctx, typ)
+	for _, binding := range structDescriptor.Fields {
+		for _, toName := range binding.ToNames {
+			new := &bindingTo{
+				binding: binding,
+				toName:  toName,
+			}
+			for _, old := range orderedBindings {
+				if old.toName != toName {
+					continue
+				}
+				old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding)
+			}
+			orderedBindings = append(orderedBindings, new)
+		}
+	}
+	if len(orderedBindings) == 0 {
+		return &emptyStructEncoder{}
+	}
+	finalOrderedFields := []structFieldTo{}
+	for _, bindingTo := range orderedBindings {
+		if !bindingTo.ignored {
+			finalOrderedFields = append(finalOrderedFields, structFieldTo{
+				encoder: bindingTo.binding.Encoder.(*structFieldEncoder),
+				toName:  bindingTo.toName,
+			})
+		}
+	}
+	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)}
+	}
+}
+
+func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
+	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) {
+				return true, false
+			} else if len(new.levels) > len(old.levels) {
+				return false, true
+			} else {
+				return true, true
+			}
+		} else {
+			return true, false
+		}
+	} else {
+		if oldTagged {
+			return true, false
+		}
+		if len(old.levels) > len(new.levels) {
+			return true, false
+		} else if len(new.levels) > len(old.levels) {
+			return false, true
+		} else {
+			return true, true
+		}
+	}
+}
+
+type structFieldEncoder struct {
+	field        reflect2.StructField
+	fieldEncoder ValEncoder
+	omitempty    bool
+}
+
+func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	fieldPtr := encoder.field.UnsafeGet(ptr)
+	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())
+	}
+}
+
+func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	fieldPtr := encoder.field.UnsafeGet(ptr)
+	return encoder.fieldEncoder.IsEmpty(fieldPtr)
+}
+
+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
+}
+
+type structEncoder struct {
+	typ    reflect2.Type
+	fields []structFieldTo
+}
+
+type structFieldTo struct {
+	encoder *structFieldEncoder
+	toName  string
+}
+
+func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteObjectStart()
+	isNotFirst := false
+	for _, field := range encoder.fields {
+		if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
+			continue
+		}
+		if field.encoder.IsEmbeddedPtrNil(ptr) {
+			continue
+		}
+		if isNotFirst {
+			stream.WriteMore()
+		}
+		stream.WriteObjectField(field.toName)
+		field.encoder.Encode(ptr, 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) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
+}
+
+type emptyStructEncoder struct {
+}
+
+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 *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)
+}
diff --git a/vendor/github.com/json-iterator/go/skip_tests/array_test.go b/vendor/github.com/json-iterator/go/skip_tests/array_test.go
new file mode 100644
index 000000000..12e42a13a
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/array_test.go
@@ -0,0 +1,15 @@
+package skip_tests
+
+func init() {
+	testCases = append(testCases, testCase{
+		ptr: (*[]interface{})(nil),
+		inputs: []string{
+			`[]`,             // valid
+			`[1]`,            // valid
+			`[  1, "hello"]`, // valid
+			`[abc]`,          // invalid
+			`[`,              // invalid
+			`[[]`,            // invalid
+		},
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/skip_tests/float64_test.go b/vendor/github.com/json-iterator/go/skip_tests/float64_test.go
new file mode 100644
index 000000000..bc90f24f5
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/float64_test.go
@@ -0,0 +1,20 @@
+package skip_tests
+
+func init() {
+	testCases = append(testCases, testCase{
+		ptr: (*float64)(nil),
+		inputs: []string{
+			"+1",    // invalid
+			"-a",    // invalid
+			"-\x00", // invalid, zero byte
+			"0.1",   // valid
+			"0..1",  // invalid, more dot
+			"1e+1",  // valid
+			"1+1",   // invalid
+			"1E1",   // valid, e or E
+			"1ee1",  // invalid
+			"100a",  // invalid
+			"10.",   // invalid
+		},
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/skip_tests/jsoniter_skip_test.go b/vendor/github.com/json-iterator/go/skip_tests/jsoniter_skip_test.go
new file mode 100644
index 000000000..bf054d1c3
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/jsoniter_skip_test.go
@@ -0,0 +1,185 @@
+package skip_tests
+
+import (
+	"bytes"
+	"encoding/json"
+	"testing"
+
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_skip_number_in_array(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[-0.12, "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	should.Nil(iter.Error)
+	should.Equal("stream", iter.ReadString())
+}
+
+func Test_skip_string_in_array(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `["hello", "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	should.Nil(iter.Error)
+	should.Equal("stream", iter.ReadString())
+}
+
+func Test_skip_null(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null , "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	if iter.ReadString() != "stream" {
+		t.FailNow()
+	}
+}
+
+func Test_skip_true(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[true , "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	if iter.ReadString() != "stream" {
+		t.FailNow()
+	}
+}
+
+func Test_skip_false(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[false , "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	if iter.ReadString() != "stream" {
+		t.FailNow()
+	}
+}
+
+func Test_skip_array(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[[1, [2, [3], 4]], "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	if iter.ReadString() != "stream" {
+		t.FailNow()
+	}
+}
+
+func Test_skip_empty_array(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ [ ], "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	if iter.ReadString() != "stream" {
+		t.FailNow()
+	}
+}
+
+func Test_skip_nested(t *testing.T) {
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`)
+	iter.ReadArray()
+	iter.Skip()
+	iter.ReadArray()
+	if iter.ReadString() != "stream" {
+		t.FailNow()
+	}
+}
+
+func Test_skip_and_return_bytes(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`)
+	iter.ReadArray()
+	skipped := iter.SkipAndReturnBytes()
+	should.Equal(`{"a" : [{"stream": "c"}], "d": 102 }`, string(skipped))
+}
+
+func Test_skip_and_return_bytes_with_reader(t *testing.T) {
+	should := require.New(t)
+	iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(`[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`), 4)
+	iter.ReadArray()
+	skipped := iter.SkipAndReturnBytes()
+	should.Equal(`{"a" : [{"stream": "c"}], "d": 102 }`, string(skipped))
+}
+
+func Test_skip_empty(t *testing.T) {
+	should := require.New(t)
+	should.NotNil(jsoniter.Get([]byte("")).LastError())
+}
+
+type TestResp struct {
+	Code uint64
+}
+
+func Benchmark_jsoniter_skip(b *testing.B) {
+	input := []byte(`
+{
+    "_shards":{
+        "total" : 5,
+        "successful" : 5,
+        "failed" : 0
+    },
+    "hits":{
+        "total" : 1,
+        "hits" : [
+            {
+                "_index" : "twitter",
+                "_type" : "tweet",
+                "_id" : "1",
+                "_source" : {
+                    "user" : "kimchy",
+                    "postDate" : "2009-11-15T14:12:12",
+                    "message" : "trying out Elasticsearch"
+                }
+            }
+        ]
+    },
+    "code": 200
+}`)
+	for n := 0; n < b.N; n++ {
+		result := TestResp{}
+		iter := jsoniter.ParseBytes(jsoniter.ConfigDefault, input)
+		for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
+			switch field {
+			case "code":
+				result.Code = iter.ReadUint64()
+			default:
+				iter.Skip()
+			}
+		}
+	}
+}
+
+func Benchmark_json_skip(b *testing.B) {
+	input := []byte(`
+{
+    "_shards":{
+        "total" : 5,
+        "successful" : 5,
+        "failed" : 0
+    },
+    "hits":{
+        "total" : 1,
+        "hits" : [
+            {
+                "_index" : "twitter",
+                "_type" : "tweet",
+                "_id" : "1",
+                "_source" : {
+                    "user" : "kimchy",
+                    "postDate" : "2009-11-15T14:12:12",
+                    "message" : "trying out Elasticsearch"
+                }
+            }
+        ]
+    },
+    "code": 200
+}`)
+	for n := 0; n < b.N; n++ {
+		result := TestResp{}
+		json.Unmarshal(input, &result)
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/skip_tests/skip_test.go b/vendor/github.com/json-iterator/go/skip_tests/skip_test.go
new file mode 100644
index 000000000..3295e6f4c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/skip_test.go
@@ -0,0 +1,45 @@
+package skip_tests
+
+import (
+	"encoding/json"
+	"errors"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"io"
+	"reflect"
+	"testing"
+)
+
+type testCase struct {
+	ptr    interface{}
+	inputs []string
+}
+
+var testCases []testCase
+
+func Test_skip(t *testing.T) {
+	for _, testCase := range testCases {
+		valType := reflect.TypeOf(testCase.ptr).Elem()
+		for _, input := range testCase.inputs {
+			t.Run(input, func(t *testing.T) {
+				should := require.New(t)
+				ptrVal := reflect.New(valType)
+				stdErr := json.Unmarshal([]byte(input), ptrVal.Interface())
+				iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
+				iter.Skip()
+				iter.ReadNil() // trigger looking forward
+				err := iter.Error
+				if err == io.EOF {
+					err = nil
+				} else {
+					err = errors.New("remaining bytes")
+				}
+				if stdErr == nil {
+					should.Nil(err)
+				} else {
+					should.NotNil(err)
+				}
+			})
+		}
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/skip_tests/string_test.go b/vendor/github.com/json-iterator/go/skip_tests/string_test.go
new file mode 100644
index 000000000..d37777165
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/string_test.go
@@ -0,0 +1,17 @@
+package skip_tests
+
+func init() {
+	testCases = append(testCases, testCase{
+		ptr: (*string)(nil),
+		inputs: []string{
+			`""`,       // valid
+			`"hello"`,  // valid
+			`"`,        // invalid
+			`"\"`,      // invalid
+			`"\x00"`,   // invalid
+			"\"\x00\"", // invalid
+			"\"\t\"",   // invalid
+			`"\t"`,     // valid
+		},
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/skip_tests/struct_test.go b/vendor/github.com/json-iterator/go/skip_tests/struct_test.go
new file mode 100644
index 000000000..8392e828d
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/skip_tests/struct_test.go
@@ -0,0 +1,19 @@
+package skip_tests
+
+func init() {
+	testCases = append(testCases, testCase{
+		ptr: (*struct{})(nil),
+		inputs: []string{
+			`{}`,                         // valid
+			`{"hello":"world"}`,          // valid
+			`{hello:"world"}`,            // invalid
+			`{"hello:"world"}`,           // invalid
+			`{"hello","world"}`,          // invalid
+			`{"hello":{}`,                // invalid
+			`{"hello":{}}`,               // valid
+			`{"hello":{}}}`,              // invalid
+			`{"hello":  {  "hello": 1}}`, // valid
+			`{abc}`,                      // invalid
+		},
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/stream.go
new file mode 100644
index 000000000..17662fded
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/stream.go
@@ -0,0 +1,211 @@
+package jsoniter
+
+import (
+	"io"
+)
+
+// 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
+}
+
+// NewStream create new stream instance.
+// cfg can be jsoniter.ConfigDefault.
+// out can be nil if write to internal buffer.
+// bufSize is the initial size for the internal buffer in bytes.
+func NewStream(cfg API, out io.Writer, bufSize int) *Stream {
+	return &Stream{
+		cfg:       cfg.(*frozenConfig),
+		out:       out,
+		buf:       make([]byte, 0, bufSize),
+		Error:     nil,
+		indention: 0,
+	}
+}
+
+// Pool returns a pool can provide more stream with same configuration
+func (stream *Stream) Pool() StreamPool {
+	return stream.cfg
+}
+
+// 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]
+}
+
+// Available returns how many bytes are unused in the buffer.
+func (stream *Stream) Available() int {
+	return cap(stream.buf) - len(stream.buf)
+}
+
+// Buffered returns the number of bytes that have been written into the current buffer.
+func (stream *Stream) Buffered() int {
+	return len(stream.buf)
+}
+
+// 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
+}
+
+// Write writes the contents of p into the buffer.
+// It returns the number of bytes written.
+// 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
+	}
+	return len(p), nil
+}
+
+// WriteByte writes a single byte.
+func (stream *Stream) writeByte(c byte) {
+	stream.buf = append(stream.buf, c)
+}
+
+func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
+	stream.buf = append(stream.buf, c1, c2)
+}
+
+func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
+	stream.buf = append(stream.buf, c1, c2, c3)
+}
+
+func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
+	stream.buf = append(stream.buf, c1, c2, c3, c4)
+}
+
+func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
+	stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
+}
+
+// Flush writes any buffered data to the underlying io.Writer.
+func (stream *Stream) Flush() error {
+	if stream.out == nil {
+		return nil
+	}
+	if stream.Error != nil {
+		return stream.Error
+	}
+	n, err := stream.out.Write(stream.buf)
+	if err != nil {
+		if stream.Error == nil {
+			stream.Error = err
+		}
+		return err
+	}
+	stream.buf = stream.buf[n:]
+	return nil
+}
+
+// WriteRaw write string out without quotes, just like []byte
+func (stream *Stream) WriteRaw(s string) {
+	stream.buf = append(stream.buf, s...)
+}
+
+// WriteNil write null to stream
+func (stream *Stream) WriteNil() {
+	stream.writeFourBytes('n', 'u', 'l', 'l')
+}
+
+// WriteTrue write true to stream
+func (stream *Stream) WriteTrue() {
+	stream.writeFourBytes('t', 'r', 'u', 'e')
+}
+
+// WriteFalse write false to stream
+func (stream *Stream) WriteFalse() {
+	stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
+}
+
+// WriteBool write true or false into stream
+func (stream *Stream) WriteBool(val bool) {
+	if val {
+		stream.WriteTrue()
+	} else {
+		stream.WriteFalse()
+	}
+}
+
+// WriteObjectStart write { with possible indention
+func (stream *Stream) WriteObjectStart() {
+	stream.indention += stream.cfg.indentionStep
+	stream.writeByte('{')
+	stream.writeIndention(0)
+}
+
+// WriteObjectField write "field": with possible indention
+func (stream *Stream) WriteObjectField(field string) {
+	stream.WriteString(field)
+	if stream.indention > 0 {
+		stream.writeTwoBytes(':', ' ')
+	} else {
+		stream.writeByte(':')
+	}
+}
+
+// WriteObjectEnd write } with possible indention
+func (stream *Stream) WriteObjectEnd() {
+	stream.writeIndention(stream.cfg.indentionStep)
+	stream.indention -= stream.cfg.indentionStep
+	stream.writeByte('}')
+}
+
+// WriteEmptyObject write {}
+func (stream *Stream) WriteEmptyObject() {
+	stream.writeByte('{')
+	stream.writeByte('}')
+}
+
+// WriteMore write , with possible indention
+func (stream *Stream) WriteMore() {
+	stream.writeByte(',')
+	stream.writeIndention(0)
+	stream.Flush()
+}
+
+// WriteArrayStart write [ with possible indention
+func (stream *Stream) WriteArrayStart() {
+	stream.indention += stream.cfg.indentionStep
+	stream.writeByte('[')
+	stream.writeIndention(0)
+}
+
+// WriteEmptyArray write []
+func (stream *Stream) WriteEmptyArray() {
+	stream.writeTwoBytes('[', ']')
+}
+
+// WriteArrayEnd write ] with possible indention
+func (stream *Stream) WriteArrayEnd() {
+	stream.writeIndention(stream.cfg.indentionStep)
+	stream.indention -= stream.cfg.indentionStep
+	stream.writeByte(']')
+}
+
+func (stream *Stream) writeIndention(delta int) {
+	if stream.indention == 0 {
+		return
+	}
+	stream.writeByte('\n')
+	toWrite := stream.indention - delta
+	for i := 0; i < toWrite; i++ {
+		stream.buf = append(stream.buf, ' ')
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go
new file mode 100644
index 000000000..f318d2c59
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/stream_float.go
@@ -0,0 +1,94 @@
+package jsoniter
+
+import (
+	"math"
+	"strconv"
+)
+
+var pow10 []uint64
+
+func init() {
+	pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
+}
+
+// WriteFloat32 write float32 to stream
+func (stream *Stream) WriteFloat32(val float32) {
+	abs := math.Abs(float64(val))
+	fmt := byte('f')
+	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+	if abs != 0 {
+		if float32(abs) < 1e-6 || float32(abs) >= 1e21 {
+			fmt = 'e'
+		}
+	}
+	stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32)
+}
+
+// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster
+func (stream *Stream) WriteFloat32Lossy(val float32) {
+	if val < 0 {
+		stream.writeByte('-')
+		val = -val
+	}
+	if val > 0x4ffffff {
+		stream.WriteFloat32(val)
+		return
+	}
+	precision := 6
+	exp := uint64(1000000) // 6
+	lval := uint64(float64(val)*float64(exp) + 0.5)
+	stream.WriteUint64(lval / exp)
+	fval := lval % exp
+	if fval == 0 {
+		return
+	}
+	stream.writeByte('.')
+	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]
+	}
+}
+
+// WriteFloat64 write float64 to stream
+func (stream *Stream) WriteFloat64(val float64) {
+	abs := math.Abs(val)
+	fmt := byte('f')
+	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+	if abs != 0 {
+		if abs < 1e-6 || abs >= 1e21 {
+			fmt = 'e'
+		}
+	}
+	stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64)
+}
+
+// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster
+func (stream *Stream) WriteFloat64Lossy(val float64) {
+	if val < 0 {
+		stream.writeByte('-')
+		val = -val
+	}
+	if val > 0x4ffffff {
+		stream.WriteFloat64(val)
+		return
+	}
+	precision := 6
+	exp := uint64(1000000) // 6
+	lval := uint64(val*float64(exp) + 0.5)
+	stream.WriteUint64(lval / exp)
+	fval := lval % exp
+	if fval == 0 {
+		return
+	}
+	stream.writeByte('.')
+	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]
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go
new file mode 100644
index 000000000..d1059ee4c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/stream_int.go
@@ -0,0 +1,190 @@
+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/stream_str.go b/vendor/github.com/json-iterator/go/stream_str.go
new file mode 100644
index 000000000..54c2ba0b3
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/stream_str.go
@@ -0,0 +1,372 @@
+package jsoniter
+
+import (
+	"unicode/utf8"
+)
+
+// htmlSafeSet holds the value true if the ASCII character with the given
+// array position can be safely represented inside a JSON string, embedded
+// inside of HTML <script> tags, without any additional escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), the backslash character ("\"), HTML opening and closing
+// tags ("<" and ">"), and the ampersand ("&").
+var htmlSafeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      false,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      false,
+	'=':      true,
+	'>':      false,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
+
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      true,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      true,
+	'=':      true,
+	'>':      true,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
+
+var hex = "0123456789abcdef"
+
+// WriteStringWithHTMLEscaped write string to stream with html special characters escaped
+func (stream *Stream) WriteStringWithHTMLEscaped(s string) {
+	valLen := len(s)
+	stream.buf = append(stream.buf, '"')
+	// write string, the fast path, without utf8 and escape support
+	i := 0
+	for ; i < valLen; i++ {
+		c := s[i]
+		if c < utf8.RuneSelf && htmlSafeSet[c] {
+			stream.buf = append(stream.buf, c)
+		} else {
+			break
+		}
+	}
+	if i == valLen {
+		stream.buf = append(stream.buf, '"')
+		return
+	}
+	writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen)
+}
+
+func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen int) {
+	start := i
+	// for the remaining parts, we process them char by char
+	for i < valLen {
+		if b := s[i]; b < utf8.RuneSelf {
+			if htmlSafeSet[b] {
+				i++
+				continue
+			}
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				stream.writeTwoBytes('\\', b)
+			case '\n':
+				stream.writeTwoBytes('\\', 'n')
+			case '\r':
+				stream.writeTwoBytes('\\', 'r')
+			case '\t':
+				stream.writeTwoBytes('\\', 't')
+			default:
+				// This encodes bytes < 0x20 except for \t, \n and \r.
+				// If escapeHTML is set, it also escapes <, >, and &
+				// because they can lead to security holes when
+				// user-controlled strings are rendered into JSON
+				// and served to some browsers.
+				stream.WriteRaw(`\u00`)
+				stream.writeTwoBytes(hex[b>>4], hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRuneInString(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			stream.WriteRaw(`\ufffd`)
+			i++
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR.
+		// U+2029 is PARAGRAPH SEPARATOR.
+		// They are both technically valid characters in JSON strings,
+		// but don't work in JSONP, which has to be evaluated as JavaScript,
+		// and can lead to security holes there. It is valid JSON to
+		// escape them, so we do so unconditionally.
+		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			stream.WriteRaw(`\u202`)
+			stream.writeByte(hex[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		stream.WriteRaw(s[start:])
+	}
+	stream.writeByte('"')
+}
+
+// WriteString write string to stream without html escape
+func (stream *Stream) WriteString(s string) {
+	valLen := len(s)
+	stream.buf = append(stream.buf, '"')
+	// write string, the fast path, without utf8 and escape support
+	i := 0
+	for ; i < valLen; i++ {
+		c := s[i]
+		if c > 31 && c != '"' && c != '\\' {
+			stream.buf = append(stream.buf, c)
+		} else {
+			break
+		}
+	}
+	if i == valLen {
+		stream.buf = append(stream.buf, '"')
+		return
+	}
+	writeStringSlowPath(stream, i, s, valLen)
+}
+
+func writeStringSlowPath(stream *Stream, i int, s string, valLen int) {
+	start := i
+	// for the remaining parts, we process them char by char
+	for i < valLen {
+		if b := s[i]; b < utf8.RuneSelf {
+			if safeSet[b] {
+				i++
+				continue
+			}
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				stream.writeTwoBytes('\\', b)
+			case '\n':
+				stream.writeTwoBytes('\\', 'n')
+			case '\r':
+				stream.writeTwoBytes('\\', 'r')
+			case '\t':
+				stream.writeTwoBytes('\\', 't')
+			default:
+				// This encodes bytes < 0x20 except for \t, \n and \r.
+				// If escapeHTML is set, it also escapes <, >, and &
+				// because they can lead to security holes when
+				// user-controlled strings are rendered into JSON
+				// and served to some browsers.
+				stream.WriteRaw(`\u00`)
+				stream.writeTwoBytes(hex[b>>4], hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		i++
+		continue
+	}
+	if start < len(s) {
+		stream.WriteRaw(s[start:])
+	}
+	stream.writeByte('"')
+}
diff --git a/vendor/github.com/json-iterator/go/stream_test.go b/vendor/github.com/json-iterator/go/stream_test.go
new file mode 100644
index 000000000..d407c7ab7
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/stream_test.go
@@ -0,0 +1,69 @@
+package jsoniter
+
+import (
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func Test_writeByte_should_grow_buffer(t *testing.T) {
+	should := require.New(t)
+	stream := NewStream(ConfigDefault, nil, 1)
+	stream.writeByte('1')
+	should.Equal("1", string(stream.Buffer()))
+	should.Equal(1, len(stream.buf))
+	stream.writeByte('2')
+	should.Equal("12", string(stream.Buffer()))
+	should.Equal(2, len(stream.buf))
+	stream.writeThreeBytes('3', '4', '5')
+	should.Equal("12345", string(stream.Buffer()))
+}
+
+func Test_writeBytes_should_grow_buffer(t *testing.T) {
+	should := require.New(t)
+	stream := NewStream(ConfigDefault, nil, 1)
+	stream.Write([]byte{'1', '2'})
+	should.Equal("12", string(stream.Buffer()))
+	should.Equal(2, len(stream.buf))
+	stream.Write([]byte{'3', '4', '5', '6', '7'})
+	should.Equal("1234567", string(stream.Buffer()))
+	should.Equal(7, len(stream.buf))
+}
+
+func Test_writeIndention_should_grow_buffer(t *testing.T) {
+	should := require.New(t)
+	stream := NewStream(Config{IndentionStep: 2}.Froze(), nil, 1)
+	stream.WriteVal([]int{1, 2, 3})
+	should.Equal("[\n  1,\n  2,\n  3\n]", string(stream.Buffer()))
+}
+
+func Test_writeRaw_should_grow_buffer(t *testing.T) {
+	should := require.New(t)
+	stream := NewStream(ConfigDefault, nil, 1)
+	stream.WriteRaw("123")
+	should.Nil(stream.Error)
+	should.Equal("123", string(stream.Buffer()))
+}
+
+func Test_writeString_should_grow_buffer(t *testing.T) {
+	should := require.New(t)
+	stream := NewStream(ConfigDefault, nil, 0)
+	stream.WriteString("123")
+	should.Nil(stream.Error)
+	should.Equal(`"123"`, string(stream.Buffer()))
+}
+
+type NopWriter struct {
+	bufferSize int
+}
+
+func (w *NopWriter) Write(p []byte) (n int, err error) {
+	w.bufferSize = cap(p)
+	return len(p), nil
+}
+
+func Test_flush_buffer_should_stop_grow_buffer(t *testing.T) {
+	writer := new(NopWriter)
+	NewEncoder(writer).Encode(make([]int, 10000000))
+	should := require.New(t)
+	should.Equal(8, writer.bufferSize)
+}
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..f4e7c0b2c
--- /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 -coverpkg=github.com/json-iterator/go $d
+    if [ -f profile.out ]; then
+        cat profile.out >> coverage.txt
+        rm profile.out
+    fi
+done
diff --git a/vendor/github.com/json-iterator/go/type_tests/array_test.go b/vendor/github.com/json-iterator/go/type_tests/array_test.go
new file mode 100644
index 000000000..db27d4ac8
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/array_test.go
@@ -0,0 +1,63 @@
+package test
+
+func init() {
+	testCases = append(testCases,
+		(*[4]bool)(nil),
+		(*[4]byte)(nil),
+		(*[4]float64)(nil),
+		(*[4]int32)(nil),
+		(*[4]map[int32]string)(nil),
+		(*[4]map[string]string)(nil),
+		(*[4]*bool)(nil),
+		(*[4]*float64)(nil),
+		(*[4]*int32)(nil),
+		(*[4]*map[int32]string)(nil),
+		(*[4]*map[string]string)(nil),
+		(*[4]*[4]bool)(nil),
+		(*[4]*[4]byte)(nil),
+		(*[4]*[4]float64)(nil),
+		(*[4]*[4]int32)(nil),
+		(*[4]*[4]*string)(nil),
+		(*[4]*[4]string)(nil),
+		(*[4]*[4]uint8)(nil),
+		(*[4]*string)(nil),
+		(*[4]*struct {
+			String string
+			Int    int32
+			Float  float64
+			Struct struct {
+				X string
+			}
+			Slice [4]string
+			Map   map[string]string
+		})(nil),
+		(*[4]*uint8)(nil),
+		(*[4][4]bool)(nil),
+		(*[4][4]byte)(nil),
+		(*[4][4]float64)(nil),
+		(*[4][4]int32)(nil),
+		(*[4][4]*string)(nil),
+		(*[4][4]string)(nil),
+		(*[4][4]uint8)(nil),
+		(*[4]string)(nil),
+		(*[4]struct{})(nil),
+		(*[4]structEmpty)(nil),
+		(*[4]struct {
+			F *string
+		})(nil),
+		(*[4]struct {
+			String string
+			Int    int32
+			Float  float64
+			Struct struct {
+				X string
+			}
+			Slice [4]string
+			Map   map[string]string
+		})(nil),
+		(*[4]uint8)(nil),
+	)
+}
+
+type structEmpty struct{}
+type arrayAlis [4]stringAlias
diff --git a/vendor/github.com/json-iterator/go/type_tests/builtin_test.go b/vendor/github.com/json-iterator/go/type_tests/builtin_test.go
new file mode 100644
index 000000000..03dd34597
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/builtin_test.go
@@ -0,0 +1,69 @@
+package test
+
+func init() {
+	testCases = append(testCases,
+		(*bool)(nil),
+		(*boolAlias)(nil),
+		(*byte)(nil),
+		(*byteAlias)(nil),
+		(*float32)(nil),
+		(*float32Alias)(nil),
+		(*float64)(nil),
+		(*float64Alias)(nil),
+		(*int8)(nil),
+		(*int8Alias)(nil),
+		(*int16)(nil),
+		(*int16Alias)(nil),
+		(*int32)(nil),
+		(*int32Alias)(nil),
+		(*int64)(nil),
+		(*int64Alias)(nil),
+		(*string)(nil),
+		(*stringAlias)(nil),
+		(*uint8)(nil),
+		(*uint8Alias)(nil),
+		(*uint16)(nil),
+		(*uint16Alias)(nil),
+		(*uint32)(nil),
+		(*uint32Alias)(nil),
+		(*uintptr)(nil),
+		(*uintptrAlias)(nil),
+		(*struct {
+			A int8Alias    `json:"a"`
+			B int16Alias   `json:"stream"`
+			C int32Alias   `json:"c"`
+			D int64Alias   `json:"d"`
+			E uintAlias    `json:"e"`
+			F uint16Alias  `json:"f"`
+			G uint32Alias  `json:"g"`
+			H uint64Alias  `json:"h"`
+			I float32Alias `json:"i"`
+			J float64Alias `json:"j"`
+			K stringAlias  `json:"k"`
+			L intAlias     `json:"l"`
+			M uintAlias    `json:"m"`
+			N boolAlias    `json:"n"`
+			O uintptrAlias `json:"o"`
+		})(nil),
+	)
+}
+
+type boolAlias bool
+type byteAlias byte
+type float32Alias float32
+type float64Alias float64
+type ptrFloat64Alias *float64
+type int8Alias int8
+type int16Alias int16
+type int32Alias int32
+type ptrInt32Alias *int32
+type int64Alias int64
+type stringAlias string
+type ptrStringAlias *string
+type uint8Alias uint8
+type uint16Alias uint16
+type uint32Alias uint32
+type uintptrAlias uintptr
+type uintAlias uint
+type uint64Alias uint64
+type intAlias int
diff --git a/vendor/github.com/json-iterator/go/type_tests/map_key_test.go b/vendor/github.com/json-iterator/go/type_tests/map_key_test.go
new file mode 100644
index 000000000..e5bd21fb7
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/map_key_test.go
@@ -0,0 +1,43 @@
+package test
+
+import (
+	"encoding"
+	"strings"
+)
+
+func init() {
+	testCases = append(testCases,
+		(*map[stringKeyType]string)(nil),
+		(*map[structKeyType]string)(nil),
+	)
+}
+
+type stringKeyType string
+
+func (k stringKeyType) MarshalText() ([]byte, error) {
+	return []byte("MANUAL__" + k), nil
+}
+
+func (k *stringKeyType) UnmarshalText(text []byte) error {
+	*k = stringKeyType(strings.TrimPrefix(string(text), "MANUAL__"))
+	return nil
+}
+
+var _ encoding.TextMarshaler = stringKeyType("")
+var _ encoding.TextUnmarshaler = new(stringKeyType)
+
+type structKeyType struct {
+	X string
+}
+
+func (k structKeyType) MarshalText() ([]byte, error) {
+	return []byte("MANUAL__" + k.X), nil
+}
+
+func (k *structKeyType) UnmarshalText(text []byte) error {
+	k.X = strings.TrimPrefix(string(text), "MANUAL__")
+	return nil
+}
+
+var _ encoding.TextMarshaler = structKeyType{}
+var _ encoding.TextUnmarshaler = &structKeyType{}
diff --git a/vendor/github.com/json-iterator/go/type_tests/map_test.go b/vendor/github.com/json-iterator/go/type_tests/map_test.go
new file mode 100644
index 000000000..614f7bcd5
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/map_test.go
@@ -0,0 +1,60 @@
+package test
+
+func init() {
+	testCases = append(testCases,
+		(*map[int8]string)(nil),
+		(*map[int16]string)(nil),
+		(*map[int32]string)(nil),
+		(*map[int64]string)(nil),
+		(*map[string][4]string)(nil),
+		(*map[string]bool)(nil),
+		(*map[string]byte)(nil),
+		(*map[string]float64)(nil),
+		(*map[string]int32)(nil),
+		(*map[string]map[string]string)(nil),
+		(*map[string]*[4]string)(nil),
+		(*map[string]*bool)(nil),
+		(*map[string]*float64)(nil),
+		(*map[string]*int32)(nil),
+		(*map[string]*map[string]string)(nil),
+		(*map[string]*[]string)(nil),
+		(*map[string]*string)(nil),
+		(*map[string]*structVarious)(nil),
+		(*map[string]*uint8)(nil),
+		(*map[string][]string)(nil),
+		(*map[string]string)(nil),
+		(*map[string]stringAlias)(nil),
+		(*map[string]struct{})(nil),
+		(*map[string]structEmpty)(nil),
+		(*map[string]struct {
+			F *string
+		})(nil),
+		(*map[string]struct {
+			String string
+			Int    int32
+			Float  float64
+			Struct struct {
+				X string
+			}
+			Slice []string
+			Map   map[string]string
+		})(nil),
+		(*map[string]uint8)(nil),
+		(*map[stringAlias]string)(nil),
+		(*map[stringAlias]stringAlias)(nil),
+		(*map[uint8]string)(nil),
+		(*map[uint16]string)(nil),
+		(*map[uint32]string)(nil),
+	)
+}
+
+type structVarious struct {
+	String string
+	Int    int32
+	Float  float64
+	Struct struct {
+		X string
+	}
+	Slice []string
+	Map   map[string]string
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/marshaler_string_test.go b/vendor/github.com/json-iterator/go/type_tests/marshaler_string_test.go
new file mode 100644
index 000000000..c871191f4
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/marshaler_string_test.go
@@ -0,0 +1,52 @@
+package test
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"strings"
+)
+
+type StringMarshaler string
+
+func (m StringMarshaler) encode(str string) string {
+	buf := bytes.Buffer{}
+	b64 := base64.NewEncoder(base64.StdEncoding, &buf)
+	if _, err := b64.Write([]byte(str)); err != nil {
+		panic(err)
+	}
+	if err := b64.Close(); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func (m StringMarshaler) decode(str string) string {
+	if len(str) == 0 {
+		return ""
+	}
+	b64 := base64.NewDecoder(base64.StdEncoding, strings.NewReader(str))
+	bs := make([]byte, len(str))
+	if n, err := b64.Read(bs); err != nil {
+		panic(err)
+	} else {
+		bs = bs[:n]
+	}
+	return string(bs)
+}
+
+func (m StringMarshaler) MarshalJSON() ([]byte, error) {
+	return []byte(`"MANUAL__` + m.encode(string(m)) + `"`), nil
+}
+
+func (m *StringMarshaler) UnmarshalJSON(text []byte) error {
+	*m = StringMarshaler(m.decode(strings.TrimPrefix(strings.Trim(string(text), `"`), "MANUAL__")))
+	return nil
+}
+
+var _ json.Marshaler = *new(StringMarshaler)
+var _ json.Unmarshaler = new(StringMarshaler)
+
+func init() {
+	testCases = append(testCases, (*StringMarshaler)(nil))
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/marshaler_struct_test.go b/vendor/github.com/json-iterator/go/type_tests/marshaler_struct_test.go
new file mode 100644
index 000000000..e235dd600
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/marshaler_struct_test.go
@@ -0,0 +1,69 @@
+package test
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"strings"
+)
+
+type structMarshaler struct {
+	X string
+}
+
+func (m structMarshaler) encode(str string) string {
+	buf := bytes.Buffer{}
+	b64 := base64.NewEncoder(base64.StdEncoding, &buf)
+	if _, err := b64.Write([]byte(str)); err != nil {
+		panic(err)
+	}
+	if err := b64.Close(); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func (m structMarshaler) decode(str string) string {
+	if len(str) == 0 {
+		return ""
+	}
+	b64 := base64.NewDecoder(base64.StdEncoding, strings.NewReader(str))
+	bs := make([]byte, len(str))
+	if n, err := b64.Read(bs); err != nil {
+		panic(err)
+	} else {
+		bs = bs[:n]
+	}
+	return string(bs)
+}
+
+func (m structMarshaler) MarshalJSON() ([]byte, error) {
+	return []byte(`"MANUAL__` + m.encode(m.X) + `"`), nil
+}
+
+func (m *structMarshaler) UnmarshalJSON(text []byte) error {
+	m.X = m.decode(strings.TrimPrefix(strings.Trim(string(text), `"`), "MANUAL__"))
+	return nil
+}
+
+var _ json.Marshaler = structMarshaler{}
+var _ json.Unmarshaler = &structMarshaler{}
+
+type structMarshalerAlias structMarshaler
+
+func init() {
+	testCases = append(testCases,
+		(*structMarshaler)(nil),
+		(*structMarshalerAlias)(nil),
+		(*struct {
+			S string
+			M structMarshaler
+			I int8
+		})(nil),
+		(*struct {
+			S string
+			M structMarshalerAlias
+			I int8
+		})(nil),
+	)
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/slice_test.go b/vendor/github.com/json-iterator/go/type_tests/slice_test.go
new file mode 100644
index 000000000..129737d5c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/slice_test.go
@@ -0,0 +1,125 @@
+package test
+
+func init() {
+	testCases = append(testCases,
+		(*[][4]bool)(nil),
+		(*[][4]byte)(nil),
+		(*[][4]float64)(nil),
+		(*[][4]int32)(nil),
+		(*[][4]*string)(nil),
+		(*[][4]string)(nil),
+		(*[][4]uint8)(nil),
+		(*[]bool)(nil),
+		(*[]byte)(nil),
+		(*[]float64)(nil),
+		(*[]int32)(nil),
+		(*[]int64)(nil),
+		(*[]map[int32]string)(nil),
+		(*[]map[string]string)(nil),
+		(*[4]*[4]bool)(nil),
+		(*[4]*[4]byte)(nil),
+		(*[4]*[4]float64)(nil),
+		(*[4]*[4]int32)(nil),
+		(*[4]*[4]*string)(nil),
+		(*[4]*[4]string)(nil),
+		(*[4]*[4]uint8)(nil),
+		(*[]*bool)(nil),
+		(*[]*float64)(nil),
+		(*[]*int32)(nil),
+		(*[]*map[int32]string)(nil),
+		(*[]*map[string]string)(nil),
+		(*[]*[]bool)(nil),
+		(*[]*[]byte)(nil),
+		(*[]*[]float64)(nil),
+		(*[]*[]int32)(nil),
+		(*[]*[]*string)(nil),
+		(*[]*[]string)(nil),
+		(*[]*[]uint8)(nil),
+		(*[]*string)(nil),
+		(*[]*struct {
+			String string
+			Int    int32
+			Float  float64
+			Struct struct {
+				X string
+			}
+			Slice []string
+			Map   map[string]string
+		})(nil),
+		(*[]*uint8)(nil),
+		(*[][]bool)(nil),
+		(*[][]byte)(nil),
+		(*[][]float64)(nil),
+		(*[][]int32)(nil),
+		(*[][]*string)(nil),
+		(*[][]string)(nil),
+		(*[][]uint8)(nil),
+		(*[]string)(nil),
+		(*[]struct{})(nil),
+		(*[]structEmpty)(nil),
+		(*[]struct {
+			F *string
+		})(nil),
+		(*[]struct {
+			String string
+			Int    int32
+			Float  float64
+			Struct struct {
+				X string
+			}
+			Slice []string
+			Map   map[string]string
+		})(nil),
+		(*[]uint8)(nil),
+		(*[]jsonMarshaler)(nil),
+		(*[]jsonMarshalerMap)(nil),
+		(*[]textMarshaler)(nil),
+		(*[]textMarshalerMap)(nil),
+	)
+}
+
+type jsonMarshaler struct {
+	Id string `json:"id,omitempty" db:"id"`
+}
+
+func (p *jsonMarshaler) MarshalJSON() ([]byte, error) {
+	return []byte(`{}`), nil
+}
+
+func (p *jsonMarshaler) UnmarshalJSON(input []byte) error {
+	p.Id = "hello"
+	return nil
+}
+
+type jsonMarshalerMap map[int]int
+
+func (p *jsonMarshalerMap) MarshalJSON() ([]byte, error) {
+	return []byte(`{}`), nil
+}
+
+func (p *jsonMarshalerMap) UnmarshalJSON(input []byte) error {
+	return nil
+}
+
+type textMarshaler struct {
+	Id string `json:"id,omitempty" db:"id"`
+}
+
+func (p *textMarshaler) MarshalText() ([]byte, error) {
+	return []byte(`{}`), nil
+}
+
+func (p *textMarshaler) UnmarshalText(input []byte) error {
+	p.Id = "hello"
+	return nil
+}
+
+type textMarshalerMap map[int]int
+
+func (p *textMarshalerMap) MarshalText() ([]byte, error) {
+	return []byte(`{}`), nil
+}
+
+func (p *textMarshalerMap) UnmarshalText(input []byte) error {
+	return nil
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/struct_embedded_test.go b/vendor/github.com/json-iterator/go/type_tests/struct_embedded_test.go
new file mode 100644
index 000000000..3fb3f1107
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/struct_embedded_test.go
@@ -0,0 +1,233 @@
+package test
+
+func init() {
+	testCases = append(testCases,
+		(*struct {
+			EmbeddedFloat64
+		})(nil),
+		(*struct {
+			EmbeddedInt32
+		})(nil),
+		(*struct {
+			F1 float64
+			StringMarshaler
+			F2 int32
+		})(nil),
+		(*struct {
+			EmbeddedMapStringString
+		})(nil),
+		(*struct {
+			*EmbeddedFloat64
+		})(nil),
+		(*struct {
+			*EmbeddedInt32
+		})(nil),
+		(*struct {
+			*EmbeddedMapStringString
+		})(nil),
+		(*struct {
+			*EmbeddedSliceString
+		})(nil),
+		(*struct {
+			*EmbeddedString
+		})(nil),
+		(*struct {
+			*EmbeddedStruct
+		})(nil),
+		(*struct {
+			EmbeddedSliceString
+		})(nil),
+		(*struct {
+			EmbeddedString
+		})(nil),
+		(*struct {
+			EmbeddedString `json:"othername"`
+		})(nil),
+		(*struct {
+			EmbeddedStruct
+		})(nil),
+		(*struct {
+			F1 float64
+			StringTextMarshaler
+			F2 int32
+		})(nil),
+		(*OverlapDifferentLevels)(nil),
+		(*IgnoreDeeperLevel)(nil),
+		(*SameLevel1BothTagged)(nil),
+		(*SameLevel1NoTags)(nil),
+		(*SameLevel1Tagged)(nil),
+		(*SameLevel2BothTagged)(nil),
+		(*SameLevel2NoTags)(nil),
+		(*SameLevel2Tagged)(nil),
+		(*EmbeddedPtr)(nil),
+	)
+}
+
+type EmbeddedFloat64 float64
+type EmbeddedInt32 int32
+type EmbeddedMapStringString map[string]string
+type EmbeddedSliceString []string
+type EmbeddedString string
+type EmbeddedStruct struct {
+	String string
+	Int    int32
+	Float  float64
+	Struct struct {
+		X string
+	}
+	Slice []string
+	Map   map[string]string
+}
+
+type OverlapDifferentLevelsE1 struct {
+	F1 int32
+}
+
+type OverlapDifferentLevelsE2 struct {
+	F2 string
+}
+
+type OverlapDifferentLevels struct {
+	OverlapDifferentLevelsE1
+	OverlapDifferentLevelsE2
+	F1 string
+}
+
+type IgnoreDeeperLevelDoubleEmbedded struct {
+	F1 int32 `json:"F1"`
+}
+
+type IgnoreDeeperLevelE1 struct {
+	IgnoreDeeperLevelDoubleEmbedded
+	F1 int32
+}
+
+type IgnoreDeeperLevelE2 struct {
+	F1 int32 `json:"F1"`
+	IgnoreDeeperLevelDoubleEmbedded
+}
+
+type IgnoreDeeperLevel struct {
+	IgnoreDeeperLevelE1
+	IgnoreDeeperLevelE2
+}
+
+type SameLevel1BothTaggedE1 struct {
+	F1 int32 `json:"F1"`
+}
+
+type SameLevel1BothTaggedE2 struct {
+	F1 int32 `json:"F1"`
+}
+
+type SameLevel1BothTagged struct {
+	SameLevel1BothTaggedE1
+	SameLevel1BothTaggedE2
+}
+
+type SameLevel1NoTagsE1 struct {
+	F1 int32
+}
+
+type SameLevel1NoTagsE2 struct {
+	F1 int32
+}
+
+type SameLevel1NoTags struct {
+	SameLevel1NoTagsE1
+	SameLevel1NoTagsE2
+}
+
+type SameLevel1TaggedE1 struct {
+	F1 int32
+}
+
+type SameLevel1TaggedE2 struct {
+	F1 int32 `json:"F1"`
+}
+
+type SameLevel1Tagged struct {
+	SameLevel1TaggedE1
+	SameLevel1TaggedE2
+}
+
+type SameLevel2BothTaggedDE1 struct {
+	F1 int32 `json:"F1"`
+}
+
+type SameLevel2BothTaggedE1 struct {
+	SameLevel2BothTaggedDE1
+}
+
+// DoubleEmbedded2 TEST ONLY
+type SameLevel2BothTaggedDE2 struct {
+	F1 int32 `json:"F1"`
+}
+
+// Embedded2 TEST ONLY
+type SameLevel2BothTaggedE2 struct {
+	SameLevel2BothTaggedDE2
+}
+
+type SameLevel2BothTagged struct {
+	SameLevel2BothTaggedE1
+	SameLevel2BothTaggedE2
+}
+
+type SameLevel2NoTagsDE1 struct {
+	F1 int32
+}
+
+type SameLevel2NoTagsE1 struct {
+	SameLevel2NoTagsDE1
+}
+
+type SameLevel2NoTagsDE2 struct {
+	F1 int32
+}
+
+type SameLevel2NoTagsE2 struct {
+	SameLevel2NoTagsDE2
+}
+
+type SameLevel2NoTags struct {
+	SameLevel2NoTagsE1
+	SameLevel2NoTagsE2
+}
+
+// DoubleEmbedded1 TEST ONLY
+type SameLevel2TaggedDE1 struct {
+	F1 int32
+}
+
+// Embedded1 TEST ONLY
+type SameLevel2TaggedE1 struct {
+	SameLevel2TaggedDE1
+}
+
+// DoubleEmbedded2 TEST ONLY
+type SameLevel2TaggedDE2 struct {
+	F1 int32 `json:"F1"`
+}
+
+// Embedded2 TEST ONLY
+type SameLevel2TaggedE2 struct {
+	SameLevel2TaggedDE2
+}
+
+type SameLevel2Tagged struct {
+	SameLevel2TaggedE1
+	SameLevel2TaggedE2
+}
+
+type EmbeddedPtrO1 struct {
+	O1F string
+}
+
+type EmbeddedPtrOption struct {
+	O1 *EmbeddedPtrO1
+}
+
+type EmbeddedPtr struct {
+	EmbeddedPtrOption `json:","`
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/struct_field_case_test.go b/vendor/github.com/json-iterator/go/type_tests/struct_field_case_test.go
new file mode 100644
index 000000000..567f290ba
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/struct_field_case_test.go
@@ -0,0 +1,30 @@
+package test
+
+func init() {
+	testCases = append(testCases,
+		(*struct {
+			Upper bool `json:"M"`
+			Lower bool `json:"m"`
+		})(nil),
+	)
+	asymmetricTestCases = append(asymmetricTestCases, [][2]interface{}{
+		{
+			(*struct {
+				Field string
+			})(nil),
+			(*struct {
+				FIELD string
+			})(nil),
+		},
+		{
+			(*struct {
+				F1 string
+				F2 string
+				F3 string
+			})(nil),
+			(*struct {
+				F1 string
+			})(nil),
+		},
+	}...)
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/struct_tags_test.go b/vendor/github.com/json-iterator/go/type_tests/struct_tags_test.go
new file mode 100644
index 000000000..66834b87f
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/struct_tags_test.go
@@ -0,0 +1,285 @@
+package test
+
+func init() {
+	testCases = append(testCases,
+		(*EmbeddedFieldName)(nil),
+		(*StringFieldName)(nil),
+		(*StructFieldName)(nil),
+		(*struct {
+			F1 bool `json:"F1"`
+			F2 bool `json:"F2,omitempty"`
+		})(nil),
+		(*EmbeddedOmitEmpty)(nil),
+		(*struct {
+			F1 float32 `json:"F1"`
+			F2 float32 `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 int32 `json:"F1"`
+			F2 int32 `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 map[string]string `json:"F1"`
+			F2 map[string]string `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 *bool `json:"F1"`
+			F2 *bool `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 *float32 `json:"F1"`
+			F2 *float32 `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 *int32 `json:"F1"`
+			F2 *int32 `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 *map[string]string `json:"F1"`
+			F2 *map[string]string `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 *[]string `json:"F1"`
+			F2 *[]string `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 string `json:"F1"`
+			F2 string `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 *string `json:"F1"`
+			F2 *string `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F *jm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F *tm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F *sjm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F *tm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F1 *uint32 `json:"F1"`
+			F2 *uint32 `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 []string `json:"F1"`
+			F2 []string `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 string `json:"F1"`
+			F2 string `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F jm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F tm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F struct{} `json:"f,omitempty"` // omitempty is meaningless here
+		})(nil),
+		(*struct {
+			F sjm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F stm `json:"f,omitempty"`
+		})(nil),
+		(*struct {
+			F1 uint32 `json:"F1"`
+			F2 uint32 `json:"F2,omitempty"`
+		})(nil),
+		(*struct {
+			F1 bool `json:"F1"`
+			F2 bool `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 byte `json:"F1"`
+			F2 byte `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 float32 `json:"F1"`
+			F2 float32 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 float64 `json:"F1"`
+			F2 float64 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 int8 `json:"F1"`
+			F2 int8 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 int16 `json:"F1"`
+			F2 int16 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 int32 `json:"F1"`
+			F2 int32 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 string `json:"F1"`
+			F2 string `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 uint8 `json:"F1"`
+			F2 uint8 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 uint16 `json:"F1"`
+			F2 uint16 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			F1 uint32 `json:"F1"`
+			F2 uint32 `json:"F2,string"`
+		})(nil),
+		(*struct {
+			A           string            `json:"a,omitempty"`
+			B           string            `json:"b,omitempty"`
+			Annotations map[string]string `json:"annotations,omitempty"`
+		})(nil),
+		(*struct {
+			Field bool `json:",omitempty,string"`
+		})(nil),
+		(*struct {
+			Field bool `json:"中文"`
+		})(nil),
+	)
+}
+
+// S1 TEST ONLY
+type EmbeddedFieldNameS1 struct {
+	S1F string
+}
+
+// S2 TEST ONLY
+type EmbeddedFieldNameS2 struct {
+	S2F string
+}
+
+// S3 TEST ONLY
+type EmbeddedFieldNameS3 struct {
+	S3F string
+}
+
+// S4 TEST ONLY
+type EmbeddedFieldNameS4 struct {
+	S4F string
+}
+
+// S5 TEST ONLY
+type EmbeddedFieldNameS5 struct {
+	S5F string
+}
+
+// S6 TEST ONLY
+type EmbeddedFieldNameS6 struct {
+	S6F string
+}
+
+type EmbeddedFieldName struct {
+	EmbeddedFieldNameS1 `json:"F1"`
+	EmbeddedFieldNameS2 `json:"f2"`
+	EmbeddedFieldNameS3 `json:"-"`
+	EmbeddedFieldNameS4 `json:"-,"`
+	EmbeddedFieldNameS5 `json:","`
+	EmbeddedFieldNameS6 `json:""`
+}
+
+type StringFieldNameE struct {
+	E1 string
+}
+
+type StringFieldName struct {
+	F1               string `json:"F1"`
+	F2               string `json:"f2"`
+	F3               string `json:"-"`
+	F4               string `json:"-,"`
+	F5               string `json:","`
+	F6               string `json:""`
+	StringFieldNameE `json:"e"`
+}
+
+type StructFieldNameS1 struct {
+	S1F string
+}
+
+type StructFieldNameS2 struct {
+	S2F string
+}
+
+type StructFieldNameS3 struct {
+	S3F string
+}
+
+type StructFieldNameS4 struct {
+	S4F string
+}
+
+type StructFieldNameS5 struct {
+	S5F string
+}
+
+type StructFieldNameS6 struct {
+	S6F string
+}
+
+type StructFieldName struct {
+	F1 StructFieldNameS1 `json:"F1"`
+	F2 StructFieldNameS2 `json:"f2"`
+	F3 StructFieldNameS3 `json:"-"`
+	F4 StructFieldNameS4 `json:"-,"`
+	F5 StructFieldNameS5 `json:","`
+	F6 StructFieldNameS6 `json:""`
+}
+type EmbeddedOmitEmptyE struct {
+	F string `json:"F,omitempty"`
+}
+
+type EmbeddedOmitEmpty struct {
+	EmbeddedOmitEmptyE
+}
+
+type jm string
+
+func (t *jm) UnmarshalJSON(b []byte) error {
+	return nil
+}
+
+func (t jm) MarshalJSON() ([]byte, error) {
+	return []byte(`""`), nil
+}
+
+type tm string
+
+func (t *tm) UnmarshalText(b []byte) error {
+	return nil
+}
+
+func (t tm) MarshalText() ([]byte, error) {
+	return []byte(`""`), nil
+}
+
+type sjm struct{}
+
+func (t *sjm) UnmarshalJSON(b []byte) error {
+	return nil
+}
+
+func (t sjm) MarshalJSON() ([]byte, error) {
+	return []byte(`""`), nil
+}
+
+type stm struct{}
+
+func (t *stm) UnmarshalText(b []byte) error {
+	return nil
+}
+
+func (t stm) MarshalText() ([]byte, error) {
+	return []byte(`""`), nil
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/struct_test.go b/vendor/github.com/json-iterator/go/type_tests/struct_test.go
new file mode 100644
index 000000000..0cf32522a
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/struct_test.go
@@ -0,0 +1,404 @@
+package test
+
+import "time"
+
+func init() {
+	structFields1To11()
+	testCases = append(testCases,
+		(*struct1Alias)(nil),
+		(*struct {
+			F [4]*string
+		})(nil),
+		(*struct {
+			F [4]string
+		})(nil),
+		(*struct {
+			F1 [4]stringAlias
+			F2 arrayAlis
+		})(nil),
+		(*struct {
+			F1 [4]string
+			F2 [4]string
+			F3 [4]string
+		})(nil),
+		(*struct {
+			F [4]struct {
+				F1 string
+				F2 string
+				F3 string
+			}
+		})(nil),
+		(*struct{})(nil),
+		(*structEmpty)(nil),
+		(*struct {
+			Byte1   byte
+			Byte2   byte
+			Bool1   bool
+			Bool2   bool
+			Int8    int8
+			Int16   int16
+			Int32   int32
+			Int64   int64
+			Uint8   uint8
+			Uint16  uint16
+			Uint32  uint32
+			Uint64  uint64
+			Float32 float32
+			Float64 float64
+			String1 string
+			String2 string
+		})(nil),
+		(*struct {
+			F float64
+		})(nil),
+		(*struct {
+			F float64Alias
+		})(nil),
+		(*struct {
+			F1 float64
+			F2 float64
+			F3 float64
+		})(nil),
+		(*struct {
+			F1 float64Alias
+			F2 float64Alias
+			F3 float64Alias
+		})(nil),
+		(*struct {
+			F int32
+		})(nil),
+		(*struct {
+			F int32Alias
+		})(nil),
+		(*struct {
+			F1 int32
+			F2 int32
+			F3 int32
+		})(nil),
+		(*struct {
+			F1 int32Alias
+			F2 int32Alias
+			F3 int32Alias
+		})(nil),
+		(*struct {
+			F int64
+		})(nil),
+		(*struct {
+			F map[int32]*string
+		})(nil),
+		(*struct {
+			F map[int32]string
+		})(nil),
+		(*struct {
+			F map[int32]struct {
+				F1 string
+				F2 string
+				F3 string
+			}
+		})(nil),
+		(*struct {
+			F map[string]*string
+		})(nil),
+		(*struct {
+			F map[string]string
+		})(nil),
+		(*struct {
+			F map[string]struct {
+				F1 string
+				F2 string
+				F3 string
+			}
+		})(nil),
+		(*struct {
+			F *float64
+		})(nil),
+		(*struct {
+			F1 *float64Alias
+			F2 ptrFloat64Alias
+			F3 *ptrFloat64Alias
+		})(nil),
+		(*struct {
+			F *int32
+		})(nil),
+		(*struct {
+			F1 *int32Alias
+			F2 ptrInt32Alias
+			F3 *ptrInt32Alias
+		})(nil),
+		(*struct {
+			F **struct{}
+		})(nil),
+		(*struct {
+			F **struct {
+				F1 string
+				F2 string
+				F3 string
+			}
+		})(nil),
+		(*struct {
+			F *string
+		})(nil),
+		(*struct {
+			F1 *stringAlias
+			F2 ptrStringAlias
+			F3 *ptrStringAlias
+		})(nil),
+		(*struct {
+			F *struct{}
+		})(nil),
+		(*struct {
+			F *struct {
+				F1 string
+				F2 string
+				F3 string
+			}
+		})(nil),
+		(*struct {
+			F1 *float64
+			F2 *float64
+			F3 *float64
+		})(nil),
+		(*struct {
+			F1 *int32
+			F2 *int32
+			F3 *int32
+		})(nil),
+		(*struct {
+			F1 *string
+			F2 *string
+			F3 *string
+		})(nil),
+		(*struct {
+			F []*string
+		})(nil),
+		(*struct {
+			F []string
+		})(nil),
+		(*struct {
+			F1 []stringAlias
+			F2 stringAlias
+		})(nil),
+		(*struct {
+			F1 []string
+			F2 []string
+			F3 []string
+		})(nil),
+		(*struct {
+			F []struct {
+				F1 string
+				F2 string
+				F3 string
+			}
+		})(nil),
+		(*struct {
+			F string
+		})(nil),
+		(*struct {
+			F stringAlias
+		})(nil),
+		(*struct {
+			F1 string
+			F2 string
+			F3 string
+		})(nil),
+		(*struct {
+			F1 stringAlias
+			F2 stringAlias
+			F3 stringAlias
+		})(nil),
+		(*struct {
+			F1 struct{}
+			F2 struct{}
+			F3 struct{}
+		})(nil),
+		(*struct {
+			F struct{}
+		})(nil),
+		(*struct {
+			F structEmpty
+		})(nil),
+		(*struct {
+			F struct {
+				F1 float32
+				F2 float32
+				F3 float32
+			}
+		})(nil),
+		(*struct {
+			F struct {
+				F float32
+			}
+		})(nil),
+		(*struct {
+			F struct2
+		})(nil),
+		(*struct {
+			F struct {
+				F1 int32
+				F2 int32
+				F3 int32
+			}
+		})(nil),
+		(*struct {
+			F struct {
+				F1 string
+				F2 string
+				F3 string
+			}
+		})(nil),
+		(*struct {
+			F struct3
+		})(nil),
+		(*struct {
+			TF1 struct {
+				F2 int
+				F1 *withTime
+			}
+		})(nil),
+		(*DeeplyNested)(nil),
+	)
+}
+
+func structFields1To11() {
+	testCases = append(testCases,
+		(*struct {
+			Field1 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+			Field3 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+			Field3 string
+			Field4 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+			Field3 string
+			Field4 string
+			Field5 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+			Field3 string
+			Field4 string
+			Field5 string
+			Field6 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+			Field3 string
+			Field4 string
+			Field5 string
+			Field6 string
+			Field7 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+			Field3 string
+			Field4 string
+			Field5 string
+			Field6 string
+			Field7 string
+			Field8 string
+		})(nil),
+		(*struct {
+			Field1 string
+			Field2 string
+			Field3 string
+			Field4 string
+			Field5 string
+			Field6 string
+			Field7 string
+			Field8 string
+			Field9 string
+		})(nil),
+		(*struct {
+			Field1  string
+			Field2  string
+			Field3  string
+			Field4  string
+			Field5  string
+			Field6  string
+			Field7  string
+			Field8  string
+			Field9  string
+			Field10 string
+		})(nil),
+		(*struct {
+			Field1  string
+			Field2  string
+			Field3  string
+			Field4  string
+			Field5  string
+			Field6  string
+			Field7  string
+			Field8  string
+			Field9  string
+			Field10 string
+			Field11 string
+		})(nil),
+	)
+}
+
+type struct1 struct {
+	Byte1   byte
+	Byte2   byte
+	Bool1   bool
+	Bool2   bool
+	Int8    int8
+	Int16   int16
+	Int32   int32
+	Uint8   uint8
+	Uint16  uint16
+	Uint32  uint32
+	Float32 float32
+	Float64 float64
+	String1 string
+	String2 string
+}
+type struct1Alias struct1
+
+type struct2 struct {
+	F float64
+}
+type struct3 struct {
+	F1 stringAlias
+	F2 stringAlias
+	F3 stringAlias
+}
+
+type withTime struct {
+	time.Time
+}
+
+func (t *withTime) UnmarshalJSON(b []byte) error {
+	return nil
+}
+func (t withTime) MarshalJSON() ([]byte, error) {
+	return []byte(`"fake"`), nil
+}
+
+type YetYetAnotherObject struct {
+	Field string
+}
+type YetAnotherObject struct {
+	Field *YetYetAnotherObject
+}
+type AnotherObject struct {
+	Field *YetAnotherObject
+}
+type DeeplyNested struct {
+	Me *AnotherObject
+}
diff --git a/vendor/github.com/json-iterator/go/type_tests/text_marshaler_string_test.go b/vendor/github.com/json-iterator/go/type_tests/text_marshaler_string_test.go
new file mode 100644
index 000000000..c08b7985c
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/text_marshaler_string_test.go
@@ -0,0 +1,57 @@
+package test
+
+import (
+	"bytes"
+	"encoding"
+	"encoding/base64"
+	"strings"
+)
+
+func init() {
+	testCases = append(testCases,
+		(*StringTextMarshaler)(nil),
+	)
+}
+
+// StringTextMarshaler TEST ONLY
+type StringTextMarshaler string
+
+func (m StringTextMarshaler) encode(str string) string {
+	buf := bytes.Buffer{}
+	b64 := base64.NewEncoder(base64.StdEncoding, &buf)
+	if _, err := b64.Write([]byte(str)); err != nil {
+		panic(err)
+	}
+	if err := b64.Close(); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func (m StringTextMarshaler) decode(str string) string {
+	if len(str) == 0 {
+		return ""
+	}
+	b64 := base64.NewDecoder(base64.StdEncoding, strings.NewReader(str))
+	bs := make([]byte, len(str))
+	if n, err := b64.Read(bs); err != nil {
+		panic(err)
+	} else {
+		bs = bs[:n]
+	}
+	return string(bs)
+}
+
+// MarshalText TEST ONLY
+func (m StringTextMarshaler) MarshalText() ([]byte, error) {
+	return []byte(`MANUAL__` + m.encode(string(m))), nil
+}
+
+// UnmarshalText TEST ONLY
+func (m *StringTextMarshaler) UnmarshalText(text []byte) error {
+	*m = StringTextMarshaler(m.decode(strings.TrimPrefix(string(text), "MANUAL__")))
+	return nil
+}
+
+var _ encoding.TextMarshaler = *new(StringTextMarshaler)
+var _ encoding.TextUnmarshaler = new(StringTextMarshaler)
diff --git a/vendor/github.com/json-iterator/go/type_tests/text_marshaler_struct_test.go b/vendor/github.com/json-iterator/go/type_tests/text_marshaler_struct_test.go
new file mode 100644
index 000000000..7c4be391e
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/text_marshaler_struct_test.go
@@ -0,0 +1,69 @@
+package test
+
+import (
+	"bytes"
+	"encoding"
+	"encoding/base64"
+	"strings"
+)
+
+func init() {
+	testCases = append(testCases,
+		(*structTextMarshaler)(nil),
+		(*structTextMarshalerAlias)(nil),
+		(*struct {
+			S string
+			M structTextMarshaler
+			I int8
+		})(nil),
+		(*struct {
+			S string
+			M structTextMarshalerAlias
+			I int8
+		})(nil),
+	)
+}
+
+type structTextMarshaler struct {
+	X string
+}
+
+func (m structTextMarshaler) encode(str string) string {
+	buf := bytes.Buffer{}
+	b64 := base64.NewEncoder(base64.StdEncoding, &buf)
+	if _, err := b64.Write([]byte(str)); err != nil {
+		panic(err)
+	}
+	if err := b64.Close(); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func (m structTextMarshaler) decode(str string) string {
+	if len(str) == 0 {
+		return ""
+	}
+	b64 := base64.NewDecoder(base64.StdEncoding, strings.NewReader(str))
+	bs := make([]byte, len(str))
+	if n, err := b64.Read(bs); err != nil {
+		panic(err)
+	} else {
+		bs = bs[:n]
+	}
+	return string(bs)
+}
+
+func (m structTextMarshaler) MarshalText() ([]byte, error) {
+	return []byte(`MANUAL__` + m.encode(m.X)), nil
+}
+
+func (m *structTextMarshaler) UnmarshalText(text []byte) error {
+	m.X = m.decode(strings.TrimPrefix(string(text), "MANUAL__"))
+	return nil
+}
+
+var _ encoding.TextMarshaler = structTextMarshaler{}
+var _ encoding.TextUnmarshaler = &structTextMarshaler{}
+
+type structTextMarshalerAlias structTextMarshaler
diff --git a/vendor/github.com/json-iterator/go/type_tests/type_test.go b/vendor/github.com/json-iterator/go/type_tests/type_test.go
new file mode 100644
index 000000000..cde433227
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/type_tests/type_test.go
@@ -0,0 +1,162 @@
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"github.com/davecgh/go-spew/spew"
+	"github.com/google/gofuzz"
+	"github.com/json-iterator/go"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+var testCases []interface{}
+var asymmetricTestCases [][2]interface{}
+
+type selectedSymmetricCase struct {
+	testCase interface{}
+}
+
+func Test_symmetric(t *testing.T) {
+	for _, testCase := range testCases {
+		selectedSymmetricCase, found := testCase.(selectedSymmetricCase)
+		if found {
+			testCases = []interface{}{selectedSymmetricCase.testCase}
+			break
+		}
+	}
+	for _, testCase := range testCases {
+		valType := reflect.TypeOf(testCase).Elem()
+		t.Run(valType.String(), func(t *testing.T) {
+			fz := fuzz.New().MaxDepth(10).NilChance(0.3)
+			for i := 0; i < 100; i++ {
+				beforePtrVal := reflect.New(valType)
+				beforePtr := beforePtrVal.Interface()
+				fz.Fuzz(beforePtr)
+				before := beforePtrVal.Elem().Interface()
+
+				jbStd, err := json.Marshal(before)
+				if err != nil {
+					t.Fatalf("failed to marshal with stdlib: %v", err)
+				}
+				if len(strings.TrimSpace(string(jbStd))) == 0 {
+					t.Fatal("stdlib marshal produced empty result and no error")
+				}
+				jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
+				if err != nil {
+					t.Fatalf("failed to marshal with jsoniter: %v", err)
+				}
+				if len(strings.TrimSpace(string(jbIter))) == 0 {
+					t.Fatal("jsoniter marshal produced empty result and no error")
+				}
+				if string(jbStd) != string(jbIter) {
+					t.Fatalf("marshal expected:\n    %s\ngot:\n    %s\nobj:\n    %s",
+						indent(jbStd, "    "), indent(jbIter, "    "), dump(before))
+				}
+
+				afterStdPtrVal := reflect.New(valType)
+				afterStdPtr := afterStdPtrVal.Interface()
+				err = json.Unmarshal(jbIter, afterStdPtr)
+				if err != nil {
+					t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n    %s",
+						err, indent(jbIter, "    "))
+				}
+				afterIterPtrVal := reflect.New(valType)
+				afterIterPtr := afterIterPtrVal.Interface()
+				err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, afterIterPtr)
+				if err != nil {
+					t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n    %s",
+						err, indent(jbIter, "    "))
+				}
+				afterStd := afterStdPtrVal.Elem().Interface()
+				afterIter := afterIterPtrVal.Elem().Interface()
+				if fingerprint(afterStd) != fingerprint(afterIter) {
+					t.Fatalf("unmarshal expected:\n    %s\ngot:\n    %s\nvia:\n    %s",
+						dump(afterStd), dump(afterIter), indent(jbIter, "    "))
+				}
+			}
+		})
+	}
+}
+
+func Test_asymmetric(t *testing.T) {
+	for _, testCase := range asymmetricTestCases {
+		fromType := reflect.TypeOf(testCase[0]).Elem()
+		toType := reflect.TypeOf(testCase[1]).Elem()
+		fz := fuzz.New().MaxDepth(10).NilChance(0.3)
+		for i := 0; i < 100; i++ {
+			beforePtrVal := reflect.New(fromType)
+			beforePtr := beforePtrVal.Interface()
+			fz.Fuzz(beforePtr)
+			before := beforePtrVal.Elem().Interface()
+
+			jbStd, err := json.Marshal(before)
+			if err != nil {
+				t.Fatalf("failed to marshal with stdlib: %v", err)
+			}
+			if len(strings.TrimSpace(string(jbStd))) == 0 {
+				t.Fatal("stdlib marshal produced empty result and no error")
+			}
+			jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
+			if err != nil {
+				t.Fatalf("failed to marshal with jsoniter: %v", err)
+			}
+			if len(strings.TrimSpace(string(jbIter))) == 0 {
+				t.Fatal("jsoniter marshal produced empty result and no error")
+			}
+			if string(jbStd) != string(jbIter) {
+				t.Fatalf("marshal expected:\n    %s\ngot:\n    %s\nobj:\n    %s",
+					indent(jbStd, "    "), indent(jbIter, "    "), dump(before))
+			}
+
+			afterStdPtrVal := reflect.New(toType)
+			afterStdPtr := afterStdPtrVal.Interface()
+			err = json.Unmarshal(jbIter, afterStdPtr)
+			if err != nil {
+				t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n    %s",
+					err, indent(jbIter, "    "))
+			}
+			afterIterPtrVal := reflect.New(toType)
+			afterIterPtr := afterIterPtrVal.Interface()
+			err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, afterIterPtr)
+			if err != nil {
+				t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n    %s",
+					err, indent(jbIter, "    "))
+			}
+			afterStd := afterStdPtrVal.Elem().Interface()
+			afterIter := afterIterPtrVal.Elem().Interface()
+			if fingerprint(afterStd) != fingerprint(afterIter) {
+				t.Fatalf("unmarshal expected:\n    %s\ngot:\n    %s\nvia:\n    %s",
+					dump(afterStd), dump(afterIter), indent(jbIter, "    "))
+			}
+		}
+	}
+}
+
+const indentStr = ">  "
+
+func fingerprint(obj interface{}) string {
+	c := spew.ConfigState{
+		SortKeys: true,
+		SpewKeys: true,
+	}
+	return c.Sprintf("%v", obj)
+}
+
+func dump(obj interface{}) string {
+	cfg := spew.ConfigState{
+		Indent: indentStr,
+	}
+	return cfg.Sdump(obj)
+}
+
+func indent(src []byte, prefix string) string {
+	var buf bytes.Buffer
+	err := json.Indent(&buf, src, prefix, indentStr)
+	if err != nil {
+		return fmt.Sprintf("!!! %v", err)
+	}
+	return buf.String()
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/array_test.go b/vendor/github.com/json-iterator/go/value_tests/array_test.go
new file mode 100644
index 000000000..75ce27afd
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/array_test.go
@@ -0,0 +1,20 @@
+package test
+
+func init() {
+	two := float64(2)
+	marshalCases = append(marshalCases,
+		[1]*float64{nil},
+		[1]*float64{&two},
+		[2]*float64{},
+	)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (*[0]int)(nil),
+		input: `[1]`,
+	}, unmarshalCase{
+		ptr:   (*[1]int)(nil),
+		input: `[2]`,
+	}, unmarshalCase{
+		ptr:   (*[1]int)(nil),
+		input: `[]`,
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/bool_test.go b/vendor/github.com/json-iterator/go/value_tests/bool_test.go
new file mode 100644
index 000000000..40d8ca931
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/bool_test.go
@@ -0,0 +1,10 @@
+package test
+
+func init() {
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr: (*struct {
+			Field bool `json:"field"`
+		})(nil),
+		input: `{"field": null}`,
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/eface_test.go b/vendor/github.com/json-iterator/go/value_tests/eface_test.go
new file mode 100644
index 000000000..9d22ea92b
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/eface_test.go
@@ -0,0 +1,78 @@
+package test
+
+func init() {
+	var pEFace = func(val interface{}) *interface{} {
+		return &val
+	}
+	var pInt = func(val int) *int {
+		return &val
+	}
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (**interface{})(nil),
+		input: `"hello"`,
+	}, unmarshalCase{
+		ptr:   (**interface{})(nil),
+		input: `1e1`,
+	}, unmarshalCase{
+		ptr:   (**interface{})(nil),
+		input: `1.0e1`,
+	}, unmarshalCase{
+		ptr:   (*[]interface{})(nil),
+		input: `[1.0e1]`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			Field interface{}
+		})(nil),
+		input: `{"field":"hello"}`,
+	}, unmarshalCase{
+		obj: func() interface{} {
+			type TestData struct {
+				Name string `json:"name"`
+			}
+			o := &TestData{}
+			return &o
+		},
+		input: `{"name":"value"}`,
+	}, unmarshalCase{
+		obj: func() interface{} {
+			b := true
+			return &struct {
+				Field interface{} `json:"field"`
+			}{&b}
+		},
+		input: `{"field": null}`,
+	}, unmarshalCase{
+		obj: func() interface{} {
+			var pb *bool
+			return &struct {
+				Field interface{} `json:"field"`
+			}{&pb}
+		},
+		input: `{"field": null}`,
+	}, unmarshalCase{
+		obj: func() interface{} {
+			b := true
+			pb := &b
+			return &struct {
+				Field interface{} `json:"field"`
+			}{&pb}
+		},
+		input: `{"field": null}`,
+	})
+	marshalCases = append(marshalCases,
+		pEFace("hello"),
+		struct {
+			Field interface{}
+		}{"hello"},
+		struct {
+			Field interface{}
+		}{struct {
+			field chan int
+		}{}},
+		struct {
+			Field interface{}
+		}{struct {
+			Field *int
+		}{pInt(100)}},
+	)
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/error_test.go b/vendor/github.com/json-iterator/go/value_tests/error_test.go
new file mode 100644
index 000000000..175a24e53
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/error_test.go
@@ -0,0 +1,36 @@
+package test
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"reflect"
+	"testing"
+)
+
+func Test_errorInput(t *testing.T) {
+	for _, testCase := range unmarshalCases {
+		if testCase.obj != nil {
+			continue
+		}
+		valType := reflect.TypeOf(testCase.ptr).Elem()
+		t.Run(valType.String(), func(t *testing.T) {
+			for _, data := range []string{
+				`x`,
+				`n`,
+				`nul`,
+				`{x}`,
+				`{"x"}`,
+				`{"x": "y"x}`,
+				`{"x": "y"`,
+				`{"x": "y", "a"}`,
+				`[`,
+				`[{"x": "y"}`,
+			} {
+				ptrVal := reflect.New(valType)
+				ptr := ptrVal.Interface()
+				err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(data), ptr)
+				require.Error(t, err, "on input %q", data)
+			}
+		})
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/float_test.go b/vendor/github.com/json-iterator/go/value_tests/float_test.go
new file mode 100644
index 000000000..3c00b2694
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/float_test.go
@@ -0,0 +1,129 @@
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"strconv"
+	"testing"
+)
+
+func Test_read_float(t *testing.T) {
+	inputs := []string{
+		`1.1`, `1000`, `9223372036854775807`, `12.3`, `-12.3`, `720368.54775807`, `720368.547758075`,
+		`1e1`, `1e+1`, `1e-1`, `1E1`, `1E+1`, `1E-1`, `-1e1`, `-1e+1`, `-1e-1`,
+	}
+	for _, input := range inputs {
+		// non-streaming
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
+			expected, err := strconv.ParseFloat(input, 32)
+			should.Nil(err)
+			should.Equal(float32(expected), iter.ReadFloat32())
+		})
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
+			expected, err := strconv.ParseFloat(input, 64)
+			should.Nil(err)
+			should.Equal(expected, iter.ReadFloat64())
+		})
+		// streaming
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input+","), 2)
+			expected, err := strconv.ParseFloat(input, 32)
+			should.Nil(err)
+			should.Equal(float32(expected), iter.ReadFloat32())
+		})
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input+","), 2)
+			val := float64(0)
+			err := json.Unmarshal([]byte(input), &val)
+			should.Nil(err)
+			should.Equal(val, iter.ReadFloat64())
+		})
+	}
+}
+
+func Test_write_float32(t *testing.T) {
+	vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
+		-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteFloat32Lossy(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			output, err := json.Marshal(val)
+			should.Nil(err)
+			should.Equal(string(output), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			output, err := json.Marshal(val)
+			should.Nil(err)
+			should.Equal(string(output), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
+	stream.WriteRaw("abcdefg")
+	stream.WriteFloat32Lossy(1.123456)
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("abcdefg1.123456", buf.String())
+
+	stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
+	stream.WriteFloat32(float32(0.0000001))
+	should.Equal("1e-07", string(stream.Buffer()))
+}
+
+func Test_write_float64(t *testing.T) {
+	vals := []float64{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
+		-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteFloat64Lossy(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatFloat(val, 'f', -1, 64), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatFloat(val, 'f', -1, 64), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
+	stream.WriteRaw("abcdefg")
+	stream.WriteFloat64Lossy(1.123456)
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("abcdefg1.123456", buf.String())
+
+	stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
+	stream.WriteFloat64(float64(0.0000001))
+	should.Equal("1e-07", string(stream.Buffer()))
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/iface_test.go b/vendor/github.com/json-iterator/go/value_tests/iface_test.go
new file mode 100644
index 000000000..b0daf1e00
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/iface_test.go
@@ -0,0 +1,45 @@
+package test
+
+import "io"
+
+func init() {
+	var pCloser1 = func(str string) *io.Closer {
+		closer := io.Closer(strCloser1(str))
+		return &closer
+	}
+	var pCloser2 = func(str string) *io.Closer {
+		strCloser := strCloser2(str)
+		closer := io.Closer(&strCloser)
+		return &closer
+	}
+	marshalCases = append(marshalCases,
+		pCloser1("hello"),
+		pCloser2("hello"),
+	)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (*[]io.Closer)(nil),
+		input: "[null]",
+	}, unmarshalCase{
+		obj: func() interface{} {
+			strCloser := strCloser2("")
+			return &struct {
+				Field io.Closer
+			}{
+				&strCloser,
+			}
+		},
+		input: `{"Field": "hello"}`,
+	})
+}
+
+type strCloser1 string
+
+func (closer strCloser1) Close() error {
+	return nil
+}
+
+type strCloser2 string
+
+func (closer *strCloser2) Close() error {
+	return nil
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/int_test.go b/vendor/github.com/json-iterator/go/value_tests/int_test.go
new file mode 100644
index 000000000..9a3165ed5
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/int_test.go
@@ -0,0 +1,419 @@
+package test
+
+import (
+	"bytes"
+	"fmt"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/require"
+	"strconv"
+	"testing"
+)
+
+func init() {
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr: (*struct {
+			F1  int8
+			F2  int16
+			F3  int32
+			F4  int64
+			F5  int
+			F6  uint8
+			F7  uint16
+			F8  uint32
+			F9  uint64
+			F10 uint
+			F11 float32
+			F12 float64
+			F13 uintptr
+		})(nil),
+		input: `{
+			"f1":null,
+			"f2":null,
+			"f3":null,
+			"f4":null,
+			"f5":null,
+			"f6":null,
+			"f7":null,
+			"f8":null,
+			"f9":null,
+			"f10":null,
+			"f11":null,
+			"f12":null,
+			"f13":null
+		}`,
+	})
+}
+
+func Test_int8(t *testing.T) {
+	inputs := []string{`127`, `-128`}
+	for _, input := range inputs {
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
+			expected, err := strconv.ParseInt(input, 10, 8)
+			should.Nil(err)
+			should.Equal(int8(expected), iter.ReadInt8())
+		})
+	}
+}
+
+func Test_read_int16(t *testing.T) {
+	inputs := []string{`32767`, `-32768`}
+	for _, input := range inputs {
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
+			expected, err := strconv.ParseInt(input, 10, 16)
+			should.Nil(err)
+			should.Equal(int16(expected), iter.ReadInt16())
+		})
+	}
+}
+
+func Test_read_int32(t *testing.T) {
+	inputs := []string{`1`, `12`, `123`, `1234`, `12345`, `123456`, `2147483647`, `-2147483648`}
+	for _, input := range inputs {
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
+			expected, err := strconv.ParseInt(input, 10, 32)
+			should.Nil(err)
+			should.Equal(int32(expected), iter.ReadInt32())
+		})
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input), 2)
+			expected, err := strconv.ParseInt(input, 10, 32)
+			should.Nil(err)
+			should.Equal(int32(expected), iter.ReadInt32())
+		})
+	}
+}
+
+func Test_read_int_overflow(t *testing.T) {
+	should := require.New(t)
+	inputArr := []string{"123451", "-123451"}
+	for _, s := range inputArr {
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iter.ReadInt8()
+		should.NotNil(iter.Error)
+
+		iterU := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iterU.ReadUint8()
+		should.NotNil(iterU.Error)
+
+	}
+
+	inputArr = []string{"12345678912", "-12345678912"}
+	for _, s := range inputArr {
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iter.ReadInt16()
+		should.NotNil(iter.Error)
+
+		iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iterUint.ReadUint16()
+		should.NotNil(iterUint.Error)
+	}
+
+	inputArr = []string{"3111111111", "-3111111111", "1234232323232323235678912", "-1234567892323232323212"}
+	for _, s := range inputArr {
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iter.ReadInt32()
+		should.NotNil(iter.Error)
+
+		iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iterUint.ReadUint32()
+		should.NotNil(iterUint.Error)
+	}
+
+	inputArr = []string{"9223372036854775811", "-9523372036854775807", "1234232323232323235678912", "-1234567892323232323212"}
+	for _, s := range inputArr {
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iter.ReadInt64()
+		should.NotNil(iter.Error)
+
+		iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
+		iterUint.ReadUint64()
+		should.NotNil(iterUint.Error)
+	}
+}
+
+func Test_read_int64(t *testing.T) {
+	inputs := []string{`1`, `12`, `123`, `1234`, `12345`, `123456`, `9223372036854775807`, `-9223372036854775808`}
+	for _, input := range inputs {
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
+			expected, err := strconv.ParseInt(input, 10, 64)
+			should.Nil(err)
+			should.Equal(expected, iter.ReadInt64())
+		})
+		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input), 2)
+			expected, err := strconv.ParseInt(input, 10, 64)
+			should.Nil(err)
+			should.Equal(expected, iter.ReadInt64())
+		})
+	}
+}
+
+func Test_write_uint8(t *testing.T) {
+	vals := []uint8{0, 1, 11, 111, 255}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteUint8(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 3)
+	stream.WriteRaw("a")
+	stream.WriteUint8(100) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a100", buf.String())
+}
+
+func Test_write_int8(t *testing.T) {
+	vals := []int8{0, 1, -1, 99, 0x7f, -0x80}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteInt8(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4)
+	stream.WriteRaw("a")
+	stream.WriteInt8(-100) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a-100", buf.String())
+}
+
+func Test_write_uint16(t *testing.T) {
+	vals := []uint16{0, 1, 11, 111, 255, 0xfff, 0xffff}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteUint16(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 5)
+	stream.WriteRaw("a")
+	stream.WriteUint16(10000) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a10000", buf.String())
+}
+
+func Test_write_int16(t *testing.T) {
+	vals := []int16{0, 1, 11, 111, 255, 0xfff, 0x7fff, -0x8000}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteInt16(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 6)
+	stream.WriteRaw("a")
+	stream.WriteInt16(-10000) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a-10000", buf.String())
+}
+
+func Test_write_uint32(t *testing.T) {
+	vals := []uint32{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteUint32(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
+	stream.WriteRaw("a")
+	stream.WriteUint32(0xffffffff) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a4294967295", buf.String())
+}
+
+func Test_write_int32(t *testing.T) {
+	vals := []int32{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0x7fffffff, -0x80000000}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteInt32(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 11)
+	stream.WriteRaw("a")
+	stream.WriteInt32(-0x7fffffff) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a-2147483647", buf.String())
+}
+
+func Test_write_uint64(t *testing.T) {
+	vals := []uint64{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff,
+		0xfffffffff, 0xffffffffff, 0xfffffffffff, 0xffffffffffff, 0xfffffffffffff, 0xffffffffffffff,
+		0xfffffffffffffff, 0xffffffffffffffff}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteUint64(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
+	stream.WriteRaw("a")
+	stream.WriteUint64(0xffffffff) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a4294967295", buf.String())
+}
+
+func Test_write_int64(t *testing.T) {
+	vals := []int64{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff,
+		0xfffffffff, 0xffffffffff, 0xfffffffffff, 0xffffffffffff, 0xfffffffffffff, 0xffffffffffffff,
+		0xfffffffffffffff, 0x7fffffffffffffff, -0x8000000000000000}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteInt64(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(val, 10), buf.String())
+		})
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
+			stream.WriteVal(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatInt(val, 10), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
+	stream.WriteRaw("a")
+	stream.WriteInt64(0xffffffff) // should clear buffer
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("a4294967295", buf.String())
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/invalid_test.go b/vendor/github.com/json-iterator/go/value_tests/invalid_test.go
new file mode 100644
index 000000000..4e7320554
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/invalid_test.go
@@ -0,0 +1,236 @@
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"io"
+	"testing"
+)
+
+func Test_missing_object_end(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Metric string                 `json:"metric"`
+		Tags   map[string]interface{} `json:"tags"`
+	}
+	obj := TestObject{}
+	should.NotNil(jsoniter.UnmarshalFromString(`{"metric": "sys.777","tags": {"a":"123"}`, &obj))
+}
+
+func Test_missing_array_end(t *testing.T) {
+	should := require.New(t)
+	should.NotNil(jsoniter.UnmarshalFromString(`[1,2,3`, &[]int{}))
+}
+
+func Test_invalid_any(t *testing.T) {
+	should := require.New(t)
+	any := jsoniter.Get([]byte("[]"))
+	should.Equal(jsoniter.InvalidValue, any.Get(0.3).ValueType())
+	// is nil correct ?
+	should.Equal(nil, any.Get(0.3).GetInterface())
+
+	any = any.Get(0.3)
+	should.Equal(false, any.ToBool())
+	should.Equal(int(0), any.ToInt())
+	should.Equal(int32(0), any.ToInt32())
+	should.Equal(int64(0), any.ToInt64())
+	should.Equal(uint(0), any.ToUint())
+	should.Equal(uint32(0), any.ToUint32())
+	should.Equal(uint64(0), any.ToUint64())
+	should.Equal(float32(0), any.ToFloat32())
+	should.Equal(float64(0), any.ToFloat64())
+	should.Equal("", any.ToString())
+
+	should.Equal(jsoniter.InvalidValue, any.Get(0.1).Get(1).ValueType())
+}
+
+func Test_invalid_struct_input(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct{}
+	input := []byte{54, 141, 30}
+	obj := TestObject{}
+	should.NotNil(jsoniter.Unmarshal(input, &obj))
+}
+
+func Test_invalid_slice_input(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct{}
+	input := []byte{93}
+	obj := []string{}
+	should.NotNil(jsoniter.Unmarshal(input, &obj))
+}
+
+func Test_invalid_array_input(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct{}
+	input := []byte{93}
+	obj := [0]string{}
+	should.NotNil(jsoniter.Unmarshal(input, &obj))
+}
+
+func Test_invalid_float(t *testing.T) {
+	inputs := []string{
+		`1.e1`, // dot without following digit
+		`1.`,   // dot can not be the last char
+		``,     // empty number
+		`01`,   // extra leading zero
+		`-`,    // negative without digit
+		`--`,   // double negative
+		`--2`,  // double negative
+	}
+	for _, input := range inputs {
+		t.Run(input, func(t *testing.T) {
+			should := require.New(t)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
+			iter.Skip()
+			should.NotEqual(io.EOF, iter.Error)
+			should.NotNil(iter.Error)
+			v := float64(0)
+			should.NotNil(json.Unmarshal([]byte(input), &v))
+			iter = jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
+			iter.ReadFloat64()
+			should.NotEqual(io.EOF, iter.Error)
+			should.NotNil(iter.Error)
+			iter = jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
+			iter.ReadFloat32()
+			should.NotEqual(io.EOF, iter.Error)
+			should.NotNil(iter.Error)
+		})
+	}
+}
+
+func Test_chan(t *testing.T) {
+	t.Skip("do not support chan")
+
+	type TestObject struct {
+		MyChan  chan bool
+		MyField int
+	}
+
+	should := require.New(t)
+	obj := TestObject{}
+	str, err := json.Marshal(obj)
+	should.Nil(err)
+	should.Equal(``, str)
+}
+
+func Test_invalid_number(t *testing.T) {
+	type Message struct {
+		Number int `json:"number"`
+	}
+	obj := Message{}
+	decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(bytes.NewBufferString(`{"number":"5"}`))
+	err := decoder.Decode(&obj)
+	invalidStr := err.Error()
+	result, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(invalidStr)
+	should := require.New(t)
+	should.Nil(err)
+	result2, err := json.Marshal(invalidStr)
+	should.Nil(err)
+	should.Equal(string(result2), string(result))
+}
+
+func Test_valid(t *testing.T) {
+	should := require.New(t)
+	should.True(jsoniter.Valid([]byte(`{}`)))
+	should.False(jsoniter.Valid([]byte(`{`)))
+}
+
+func Test_nil_pointer(t *testing.T) {
+	should := require.New(t)
+	data := []byte(`{"A":0}`)
+	type T struct {
+		X int
+	}
+	var obj *T
+	err := jsoniter.Unmarshal(data, obj)
+	should.NotNil(err)
+}
+
+func Test_func_pointer_type(t *testing.T) {
+	type TestObject2 struct {
+		F func()
+	}
+	type TestObject1 struct {
+		Obj *TestObject2
+	}
+	t.Run("encode null is valid", func(t *testing.T) {
+		should := require.New(t)
+		output, err := json.Marshal(TestObject1{})
+		should.Nil(err)
+		should.Equal(`{"Obj":null}`, string(output))
+		output, err = jsoniter.Marshal(TestObject1{})
+		should.Nil(err)
+		should.Equal(`{"Obj":null}`, string(output))
+	})
+	t.Run("encode not null is invalid", func(t *testing.T) {
+		should := require.New(t)
+		_, err := json.Marshal(TestObject1{Obj: &TestObject2{}})
+		should.NotNil(err)
+		_, err = jsoniter.Marshal(TestObject1{Obj: &TestObject2{}})
+		should.NotNil(err)
+	})
+	t.Run("decode null is valid", func(t *testing.T) {
+		should := require.New(t)
+		var obj TestObject1
+		should.Nil(json.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
+		should.Nil(jsoniter.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
+	})
+	t.Run("decode not null is invalid", func(t *testing.T) {
+		should := require.New(t)
+		var obj TestObject1
+		should.NotNil(json.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
+		should.NotNil(jsoniter.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
+	})
+}
+
+func TestEOF(t *testing.T) {
+	var s string
+	err := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(&bytes.Buffer{}).Decode(&s)
+	assert.Equal(t, io.EOF, err)
+}
+
+func TestDecodeErrorType(t *testing.T) {
+	should := require.New(t)
+	var err error
+	should.Nil(jsoniter.Unmarshal([]byte("null"), &err))
+	should.NotNil(jsoniter.Unmarshal([]byte("123"), &err))
+}
+
+func Test_decode_slash(t *testing.T) {
+	should := require.New(t)
+	var obj interface{}
+	should.NotNil(json.Unmarshal([]byte("\\"), &obj))
+	should.NotNil(jsoniter.UnmarshalFromString("\\", &obj))
+}
+
+func Test_NilInput(t *testing.T) {
+	var jb []byte // nil
+	var out string
+	err := jsoniter.Unmarshal(jb, &out)
+	if err == nil {
+		t.Errorf("Expected error")
+	}
+}
+
+func Test_EmptyInput(t *testing.T) {
+	jb := []byte("")
+	var out string
+	err := jsoniter.Unmarshal(jb, &out)
+	if err == nil {
+		t.Errorf("Expected error")
+	}
+}
+
+type Foo struct {
+	A jsoniter.Any
+}
+
+func Test_nil_any(t *testing.T) {
+	should := require.New(t)
+	data, _ := jsoniter.Marshal(&Foo{})
+	should.Equal(`{"A":null}`, string(data))
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/map_test.go b/vendor/github.com/json-iterator/go/value_tests/map_test.go
new file mode 100644
index 000000000..f8ffa5a3d
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/map_test.go
@@ -0,0 +1,117 @@
+package test
+
+import (
+	"encoding/json"
+	"fmt"
+	"math/big"
+	"time"
+)
+
+func init() {
+	var pRawMessage = func(val json.RawMessage) *json.RawMessage {
+		return &val
+	}
+	nilMap := map[string]string(nil)
+	marshalCases = append(marshalCases,
+		map[string]interface{}{"abc": 1},
+		map[string]MyInterface{"hello": MyString("world")},
+		map[*big.Float]string{big.NewFloat(1.2): "2"},
+		map[string]interface{}{
+			"3": 3,
+			"1": 1,
+			"2": 2,
+		},
+		map[uint64]interface{}{
+			uint64(1): "a",
+			uint64(2): "a",
+			uint64(4): "a",
+		},
+		nilMap,
+		&nilMap,
+		map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))},
+		map[Date]bool{{}: true},
+		map[Date2]bool{{}: true},
+	)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (*map[string]string)(nil),
+		input: `{"k\"ey": "val"}`,
+	}, unmarshalCase{
+		ptr:   (*map[string]string)(nil),
+		input: `null`,
+	}, unmarshalCase{
+		ptr:   (*map[string]*json.RawMessage)(nil),
+		input: "{\"test\":[{\"key\":\"value\"}]}",
+	}, unmarshalCase{
+		ptr: (*map[Date]bool)(nil),
+		input: `{
+        "2018-12-12": true,
+        "2018-12-13": true,
+        "2018-12-14": true
+    	}`,
+	}, unmarshalCase{
+		ptr: (*map[Date2]bool)(nil),
+		input: `{
+        "2018-12-12": true,
+        "2018-12-13": true,
+        "2018-12-14": true
+    	}`,
+	})
+}
+
+type MyInterface interface {
+	Hello() string
+}
+
+type MyString string
+
+func (ms MyString) Hello() string {
+	return string(ms)
+}
+
+type Date struct {
+	time.Time
+}
+
+func (d *Date) UnmarshalJSON(b []byte) error {
+	dateStr := string(b) // something like `"2017-08-20"`
+
+	if dateStr == "null" {
+		return nil
+	}
+
+	t, err := time.Parse(`"2006-01-02"`, dateStr)
+	if err != nil {
+		return fmt.Errorf("cant parse date: %#v", err)
+	}
+
+	d.Time = t
+	return nil
+}
+
+func (d *Date) MarshalJSON() ([]byte, error) {
+	return []byte(d.Time.Format("2006-01-02")), nil
+}
+
+type Date2 struct {
+	time.Time
+}
+
+func (d Date2) UnmarshalJSON(b []byte) error {
+	dateStr := string(b) // something like `"2017-08-20"`
+
+	if dateStr == "null" {
+		return nil
+	}
+
+	t, err := time.Parse(`"2006-01-02"`, dateStr)
+	if err != nil {
+		return fmt.Errorf("cant parse date: %#v", err)
+	}
+
+	d.Time = t
+	return nil
+}
+
+func (d Date2) MarshalJSON() ([]byte, error) {
+	return []byte(d.Time.Format("2006-01-02")), nil
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/marshaler_test.go b/vendor/github.com/json-iterator/go/value_tests/marshaler_test.go
new file mode 100644
index 000000000..5459495c9
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/marshaler_test.go
@@ -0,0 +1,84 @@
+package test
+
+import (
+	"encoding"
+	"encoding/json"
+)
+
+func init() {
+	jm := json.Marshaler(jmOfStruct{})
+	tm1 := encoding.TextMarshaler(tmOfStruct{})
+	tm2 := encoding.TextMarshaler(&tmOfStructInt{})
+	marshalCases = append(marshalCases,
+		jmOfStruct{},
+		&jm,
+		tmOfStruct{},
+		&tm1,
+		tmOfStructInt{},
+		&tm2,
+		map[tmOfStruct]int{
+			{}: 100,
+		},
+		map[*tmOfStruct]int{
+			{}: 100,
+		},
+		map[encoding.TextMarshaler]int{
+			tm1: 100,
+		},
+	)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (*tmOfMap)(nil),
+		input: `"{1:2}"`,
+	}, unmarshalCase{
+		ptr:   (*tmOfMapPtr)(nil),
+		input: `"{1:2}"`,
+	})
+}
+
+type jmOfStruct struct {
+	F2 chan []byte
+}
+
+func (q jmOfStruct) MarshalJSON() ([]byte, error) {
+	return []byte(`""`), nil
+}
+
+func (q *jmOfStruct) UnmarshalJSON(value []byte) error {
+	return nil
+}
+
+type tmOfStruct struct {
+	F2 chan []byte
+}
+
+func (q tmOfStruct) MarshalText() ([]byte, error) {
+	return []byte(`""`), nil
+}
+
+func (q *tmOfStruct) UnmarshalText(value []byte) error {
+	return nil
+}
+
+type tmOfStructInt struct {
+	Field2 int
+}
+
+func (q *tmOfStructInt) MarshalText() ([]byte, error) {
+	return []byte(`"abc"`), nil
+}
+
+func (q *tmOfStructInt) UnmarshalText(value []byte) error {
+	return nil
+}
+
+type tmOfMap map[int]int
+
+func (q tmOfMap) UnmarshalText(value []byte) error {
+	return nil
+}
+
+type tmOfMapPtr map[int]int
+
+func (q *tmOfMapPtr) UnmarshalText(value []byte) error {
+	return nil
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/number_test.go b/vendor/github.com/json-iterator/go/value_tests/number_test.go
new file mode 100644
index 000000000..98ab4b5a4
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/number_test.go
@@ -0,0 +1,17 @@
+package test
+
+import "encoding/json"
+
+func init() {
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (*json.Number)(nil),
+		input: `"500"`,
+	}, unmarshalCase{
+		ptr:   (*json.Number)(nil),
+		input: `1`,
+	}, unmarshalCase{
+		ptr:   (*json.Number)(nil),
+		input: `null`,
+	})
+	marshalCases = append(marshalCases, json.Number(""))
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/ptr_test.go b/vendor/github.com/json-iterator/go/value_tests/ptr_test.go
new file mode 100644
index 000000000..222b2d43a
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/ptr_test.go
@@ -0,0 +1,39 @@
+package test
+
+func init() {
+	var pInt = func(val int) *int {
+		return &val
+	}
+	marshalCases = append(marshalCases,
+		(*int)(nil),
+		pInt(100),
+	)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		obj: func() interface{} {
+			var i int
+			return &i
+		},
+		input: "null",
+	}, unmarshalCase{
+		obj: func() interface{} {
+			var i *int
+			return &i
+		},
+		input: "10",
+	}, unmarshalCase{
+		obj: func() interface{} {
+			var i int
+			pi := &i
+			return &pi
+		},
+		input: "null",
+	}, unmarshalCase{
+		obj: func() interface{} {
+			var i int
+			pi := &i
+			ppi := &pi
+			return &ppi
+		},
+		input: "null",
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/raw_message_test.go b/vendor/github.com/json-iterator/go/value_tests/raw_message_test.go
new file mode 100644
index 000000000..eb769a1dd
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/raw_message_test.go
@@ -0,0 +1,21 @@
+package test
+
+import (
+	"encoding/json"
+)
+
+func init() {
+	marshalCases = append(marshalCases,
+		json.RawMessage("{}"),
+		struct {
+			Env   string          `json:"env"`
+			Extra json.RawMessage `json:"extra,omitempty"`
+		}{
+			Env: "jfdk",
+		},
+	)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (*json.RawMessage)(nil),
+		input: `[1,2,3]`,
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/slice_test.go b/vendor/github.com/json-iterator/go/value_tests/slice_test.go
new file mode 100644
index 000000000..3731cbe15
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/slice_test.go
@@ -0,0 +1,27 @@
+package test
+
+func init() {
+	nilSlice := []string(nil)
+	marshalCases = append(marshalCases,
+		[]interface{}{"hello"},
+		nilSlice,
+		&nilSlice,
+		[]byte{1, 2, 3},
+	)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr:   (*[]string)(nil),
+		input: "null",
+	}, unmarshalCase{
+		ptr:   (*[]string)(nil),
+		input: "[]",
+	}, unmarshalCase{
+		ptr:   (*[]byte)(nil),
+		input: "[1,2,3]",
+	}, unmarshalCase{
+		ptr:   (*[]byte)(nil),
+		input: `"aGVsbG8="`,
+	}, unmarshalCase{
+		ptr:   (*[]byte)(nil),
+		input: `"c3ViamVjdHM\/X2Q9MQ=="`,
+	})
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/string_test.go b/vendor/github.com/json-iterator/go/value_tests/string_test.go
new file mode 100644
index 000000000..5f34f9d88
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/string_test.go
@@ -0,0 +1,88 @@
+package test
+
+import (
+	"encoding/json"
+	"github.com/json-iterator/go"
+	"testing"
+	"unicode/utf8"
+)
+
+func init() {
+	marshalCases = append(marshalCases,
+		`>`,
+		`"数字山谷"`,
+		"he\u2029\u2028he",
+	)
+	for i := 0; i < utf8.RuneSelf; i++ {
+		marshalCases = append(marshalCases, string([]byte{byte(i)}))
+	}
+}
+
+func Test_read_string(t *testing.T) {
+	badInputs := []string{
+		``,
+		`"`,
+		`"\"`,
+		`"\\\"`,
+		"\"\n\"",
+		`"\U0001f64f"`,
+		`"\uD83D\u00"`,
+	}
+	for i := 0; i < 32; i++ {
+		// control characters are invalid
+		badInputs = append(badInputs, string([]byte{'"', byte(i), '"'}))
+	}
+
+	for _, input := range badInputs {
+		testReadString(t, input, "", true, "json.Unmarshal", json.Unmarshal)
+		testReadString(t, input, "", true, "jsoniter.Unmarshal", jsoniter.Unmarshal)
+		testReadString(t, input, "", true, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
+	}
+
+	goodInputs := []struct {
+		input       string
+		expectValue string
+	}{
+		{`""`, ""},
+		{`"a"`, "a"},
+		{`null`, ""},
+		{`"Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"`, "Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"},
+		{`"\uD83D"`, string([]byte{239, 191, 189})},
+		{`"\uD83D\\"`, string([]byte{239, 191, 189, '\\'})},
+		{`"\uD83D\ub000"`, string([]byte{239, 191, 189, 235, 128, 128})},
+		{`"\uD83D\ude04"`, "😄"},
+		{`"\uDEADBEEF"`, string([]byte{239, 191, 189, 66, 69, 69, 70})},
+		{`"hel\"lo"`, `hel"lo`},
+		{`"hel\\\/lo"`, `hel\/lo`},
+		{`"hel\\blo"`, `hel\blo`},
+		{`"hel\\\blo"`, "hel\\\blo"},
+		{`"hel\\nlo"`, `hel\nlo`},
+		{`"hel\\\nlo"`, "hel\\\nlo"},
+		{`"hel\\tlo"`, `hel\tlo`},
+		{`"hel\\flo"`, `hel\flo`},
+		{`"hel\\\flo"`, "hel\\\flo"},
+		{`"hel\\\rlo"`, "hel\\\rlo"},
+		{`"hel\\\tlo"`, "hel\\\tlo"},
+		{`"\u4e2d\u6587"`, "中文"},
+		{`"\ud83d\udc4a"`, "\xf0\x9f\x91\x8a"},
+	}
+
+	for _, tc := range goodInputs {
+		testReadString(t, tc.input, tc.expectValue, false, "json.Unmarshal", json.Unmarshal)
+		testReadString(t, tc.input, tc.expectValue, false, "jsoniter.Unmarshal", jsoniter.Unmarshal)
+		testReadString(t, tc.input, tc.expectValue, false, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
+	}
+}
+
+func testReadString(t *testing.T, input string, expectValue string, expectError bool, marshalerName string, marshaler func([]byte, interface{}) error) {
+	var value string
+	err := marshaler([]byte(input), &value)
+	if expectError != (err != nil) {
+		t.Errorf("%q: %s: expected error %v, got %v", input, marshalerName, expectError, err)
+		return
+	}
+	if value != expectValue {
+		t.Errorf("%q: %s: expected %q, got %q", input, marshalerName, expectValue, value)
+		return
+	}
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/struct_test.go b/vendor/github.com/json-iterator/go/value_tests/struct_test.go
new file mode 100644
index 000000000..10ace5c3b
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/struct_test.go
@@ -0,0 +1,237 @@
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"time"
+)
+
+func init() {
+	var pString = func(val string) *string {
+		return &val
+	}
+	epoch := time.Unix(0, 0)
+	unmarshalCases = append(unmarshalCases, unmarshalCase{
+		ptr: (*struct {
+			Field interface{}
+		})(nil),
+		input: `{"Field": "hello"}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			Field interface{}
+		})(nil),
+		input: `{"Field": "hello"}       `,
+	}, unmarshalCase{
+		ptr: (*struct {
+			Field int `json:"field"`
+		})(nil),
+		input: `{"field": null}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			ID      int                    `json:"id"`
+			Payload map[string]interface{} `json:"payload"`
+			buf     *bytes.Buffer
+		})(nil),
+		input: ` {"id":1, "payload":{"account":"123","password":"456"}}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			Field1 string
+		})(nil),
+		input: `{"Field\"1":"hello"}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			Field1 string
+		})(nil),
+		input: `{"\u0046ield1":"hello"}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			Field1 *string
+			Field2 *string
+		})(nil),
+		input: `{"field1": null, "field2": "world"}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			Field1 string
+			Field2 json.RawMessage
+		})(nil),
+		input: `{"field1": "hello", "field2":[1,2,3]}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			a int
+			b <-chan int
+			C int
+			d *time.Timer
+		})(nil),
+		input: `{"a": 444, "b":"bad", "C":256, "d":{"not":"a timer"}}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			A string
+			B string
+			C string
+			D string
+			E string
+			F string
+			G string
+			H string
+			I string
+			J string
+			K string
+		})(nil),
+		input: `{"a":"1","b":"2","c":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			T float64 `json:"T"`
+		})(nil),
+		input: `{"t":10.0}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			T float64 `json:"T"`
+		})(nil),
+		input: `{"T":10.0}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			T float64 `json:"t"`
+		})(nil),
+		input: `{"T":10.0}`,
+	}, unmarshalCase{
+		ptr: (*struct {
+			KeyString string       `json:"key_string"`
+			Type      string       `json:"type"`
+			Asks      [][2]float64 `json:"asks"`
+		})(nil),
+		input: `{"key_string": "KEYSTRING","type": "TYPE","asks": [[1e+66,1]]}`,
+	})
+	marshalCases = append(marshalCases,
+		struct {
+			Field map[string]interface{}
+		}{
+			map[string]interface{}{"hello": "world"},
+		},
+		struct {
+			Field  map[string]interface{}
+			Field2 string
+		}{
+			map[string]interface{}{"hello": "world"}, "",
+		},
+		struct {
+			Field interface{}
+		}{
+			1024,
+		},
+		struct {
+			Field MyInterface
+		}{
+			MyString("hello"),
+		},
+		struct {
+			F *float64
+		}{},
+		struct {
+			*time.Time
+		}{&epoch},
+		struct {
+			*StructVarious
+		}{&StructVarious{}},
+		struct {
+			*StructVarious
+			Field int
+		}{nil, 10},
+		struct {
+			Field1 int
+			Field2 [1]*float64
+		}{},
+		struct {
+			Field interface{} `json:"field,omitempty"`
+		}{},
+		struct {
+			Field MyInterface `json:"field,omitempty"`
+		}{},
+		struct {
+			Field MyInterface `json:"field,omitempty"`
+		}{MyString("hello")},
+		struct {
+			Field json.Marshaler `json:"field"`
+		}{},
+		struct {
+			Field MyInterface `json:"field"`
+		}{},
+		struct {
+			Field MyInterface `json:"field"`
+		}{MyString("hello")},
+		struct {
+			Field1 string `json:"field-1,omitempty"`
+			Field2 func() `json:"-"`
+		}{},
+		structRecursive{},
+		struct {
+			*CacheItem
+
+			// Omit bad keys
+			OmitMaxAge omit `json:"cacheAge,omitempty"`
+
+			// Add nice keys
+			MaxAge int `json:"max_age"`
+		}{
+			CacheItem: &CacheItem{
+				Key:    "value",
+				MaxAge: 100,
+			},
+			MaxAge: 20,
+		},
+		structOrder{},
+		struct {
+			Field1 *string
+			Field2 *string
+		}{Field2: pString("world")},
+		struct {
+			a int
+			b <-chan int
+			C int
+			d *time.Timer
+		}{
+			a: 42,
+			b: make(<-chan int, 10),
+			C: 21,
+			d: time.NewTimer(10 * time.Second),
+		},
+	)
+}
+
+type StructVarious struct {
+	Field0 string
+	Field1 []string
+	Field2 map[string]interface{}
+}
+
+type structRecursive struct {
+	Field1 string
+	Me     *structRecursive
+}
+
+type omit *struct{}
+type CacheItem struct {
+	Key    string `json:"key"`
+	MaxAge int    `json:"cacheAge"`
+}
+
+type orderA struct {
+	Field2 string
+}
+
+type orderC struct {
+	Field5 string
+}
+
+type orderB struct {
+	Field4 string
+	orderC
+	Field6 string
+}
+
+type structOrder struct {
+	Field1 string
+	orderA
+	Field3 string
+	orderB
+	Field7 string
+}
diff --git a/vendor/github.com/json-iterator/go/value_tests/value_test.go b/vendor/github.com/json-iterator/go/value_tests/value_test.go
new file mode 100644
index 000000000..95cfdd568
--- /dev/null
+++ b/vendor/github.com/json-iterator/go/value_tests/value_test.go
@@ -0,0 +1,80 @@
+package test
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/json-iterator/go"
+	"github.com/modern-go/reflect2"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+type unmarshalCase struct {
+	obj      func() interface{}
+	ptr      interface{}
+	input    string
+	selected bool
+}
+
+var unmarshalCases []unmarshalCase
+
+var marshalCases = []interface{}{
+	nil,
+}
+
+type selectedMarshalCase struct {
+	marshalCase interface{}
+}
+
+func Test_unmarshal(t *testing.T) {
+	for _, testCase := range unmarshalCases {
+		if testCase.selected {
+			unmarshalCases = []unmarshalCase{testCase}
+			break
+		}
+	}
+	for i, testCase := range unmarshalCases {
+		t.Run(fmt.Sprintf("[%v]%s", i, testCase.input), func(t *testing.T) {
+			should := require.New(t)
+			var obj1 interface{}
+			var obj2 interface{}
+			if testCase.obj != nil {
+				obj1 = testCase.obj()
+				obj2 = testCase.obj()
+			} else {
+				valType := reflect2.TypeOfPtr(testCase.ptr).Elem()
+				obj1 = valType.New()
+				obj2 = valType.New()
+			}
+			err1 := json.Unmarshal([]byte(testCase.input), obj1)
+			should.NoError(err1, "json")
+			err2 := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(testCase.input), obj2)
+			should.NoError(err2, "jsoniter")
+			should.Equal(obj1, obj2)
+		})
+	}
+}
+
+func Test_marshal(t *testing.T) {
+	for _, testCase := range marshalCases {
+		selectedMarshalCase, found := testCase.(selectedMarshalCase)
+		if found {
+			marshalCases = []interface{}{selectedMarshalCase.marshalCase}
+			break
+		}
+	}
+	for i, testCase := range marshalCases {
+		var name string
+		if testCase != nil {
+			name = fmt.Sprintf("[%v]%v/%s", i, testCase, reflect2.TypeOf(testCase).String())
+		}
+		t.Run(name, func(t *testing.T) {
+			should := require.New(t)
+			output1, err1 := json.Marshal(testCase)
+			should.NoError(err1, "json")
+			output2, err2 := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(testCase)
+			should.NoError(err2, "jsoniter")
+			should.Equal(string(output1), string(output2))
+		})
+	}
+}
diff --git a/vendor/github.com/modern-go/concurrent/.travis.yml b/vendor/github.com/modern-go/concurrent/.travis.yml
new file mode 100644
index 000000000..449e67cd0
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+
+go:
+  - 1.8.x
+  - 1.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/modern-go/concurrent/LICENSE b/vendor/github.com/modern-go/concurrent/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/LICENSE
@@ -0,0 +1,201 @@
+                                 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/README.md b/vendor/github.com/modern-go/concurrent/README.md
new file mode 100644
index 000000000..acab3200a
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/README.md
@@ -0,0 +1,49 @@
+# concurrent
+
+[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/concurrent/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/concurrent?badge)
+[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/concurrent)
+[![Build Status](https://travis-ci.org/modern-go/concurrent.svg?branch=master)](https://travis-ci.org/modern-go/concurrent)
+[![codecov](https://codecov.io/gh/modern-go/concurrent/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/concurrent)
+[![rcard](https://goreportcard.com/badge/github.com/modern-go/concurrent)](https://goreportcard.com/report/github.com/modern-go/concurrent)
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE)
+
+* concurrent.Map: backport sync.Map for go below 1.9
+* concurrent.Executor: goroutine with explicit ownership and cancellable
+
+# concurrent.Map
+
+because sync.Map is only available in go 1.9, we can use concurrent.Map to make code portable
+
+```go
+m := concurrent.NewMap()
+m.Store("hello", "world")
+elem, found := m.Load("hello")
+// elem will be "world"
+// found will be true
+```
+
+# concurrent.Executor
+
+```go
+executor := concurrent.NewUnboundedExecutor()
+executor.Go(func(ctx context.Context) {
+    everyMillisecond := time.NewTicker(time.Millisecond)
+    for {
+        select {
+        case <-ctx.Done():
+            fmt.Println("goroutine exited")
+            return
+        case <-everyMillisecond.C:
+            // do something
+        }
+    }
+})
+time.Sleep(time.Second)
+executor.StopAndWaitForever()
+fmt.Println("executor stopped")
+```
+
+attach goroutine to executor instance, so that we can
+
+* cancel it by stop the executor with Stop/StopAndWait/StopAndWaitForever
+* handle panic by callback: the default behavior will no longer crash your application
\ No newline at end of file
diff --git a/vendor/github.com/modern-go/concurrent/executor.go b/vendor/github.com/modern-go/concurrent/executor.go
new file mode 100644
index 000000000..623dba1ac
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/executor.go
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 000000000..aeabf8c4f
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/go_above_19.go
@@ -0,0 +1,15 @@
+//+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
new file mode 100644
index 000000000..b9c8df7f4
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/go_below_19.go
@@ -0,0 +1,33 @@
+//+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
new file mode 100644
index 000000000..9756fcc75
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/log.go
@@ -0,0 +1,13 @@
+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/map_test.go b/vendor/github.com/modern-go/concurrent/map_test.go
new file mode 100644
index 000000000..16ba3e5f7
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/map_test.go
@@ -0,0 +1,18 @@
+package concurrent_test
+
+import (
+	"github.com/modern-go/concurrent"
+	"testing"
+)
+
+func TestMap_Load(t *testing.T) {
+	m := concurrent.NewMap()
+	m.Store("hello", "world")
+	value, found := m.Load("hello")
+	if !found {
+		t.Fail()
+	}
+	if value != "world" {
+		t.Fail()
+	}
+}
diff --git a/vendor/github.com/modern-go/concurrent/test.sh b/vendor/github.com/modern-go/concurrent/test.sh
new file mode 100755
index 000000000..d1e6b2ec5
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/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 -coverpkg=github.com/modern-go/concurrent $d
+    if [ -f profile.out ]; then
+        cat profile.out >> coverage.txt
+        rm profile.out
+    fi
+done
diff --git a/vendor/github.com/modern-go/concurrent/unbounded_executor.go b/vendor/github.com/modern-go/concurrent/unbounded_executor.go
new file mode 100644
index 000000000..05a77dceb
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/unbounded_executor.go
@@ -0,0 +1,119 @@
+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/concurrent/unbounded_executor_test.go b/vendor/github.com/modern-go/concurrent/unbounded_executor_test.go
new file mode 100644
index 000000000..fe86e84a3
--- /dev/null
+++ b/vendor/github.com/modern-go/concurrent/unbounded_executor_test.go
@@ -0,0 +1,54 @@
+package concurrent_test
+
+import (
+	"context"
+	"fmt"
+	"time"
+	"github.com/modern-go/concurrent"
+)
+
+func ExampleUnboundedExecutor_Go() {
+	executor := concurrent.NewUnboundedExecutor()
+	executor.Go(func(ctx context.Context) {
+		fmt.Println("abc")
+	})
+	time.Sleep(time.Second)
+	// output: abc
+}
+
+func ExampleUnboundedExecutor_StopAndWaitForever() {
+	executor := concurrent.NewUnboundedExecutor()
+	executor.Go(func(ctx context.Context) {
+		everyMillisecond := time.NewTicker(time.Millisecond)
+		for {
+			select {
+			case <-ctx.Done():
+				fmt.Println("goroutine exited")
+				return
+			case <-everyMillisecond.C:
+				// do something
+			}
+		}
+	})
+	time.Sleep(time.Second)
+	executor.StopAndWaitForever()
+	fmt.Println("executor stopped")
+	// output:
+	// goroutine exited
+	// executor stopped
+}
+
+func ExampleUnboundedExecutor_Go_panic() {
+	concurrent.HandlePanic = func(recovered interface{}, funcName string) {
+		fmt.Println(funcName)
+	}
+	executor := concurrent.NewUnboundedExecutor()
+	executor.Go(willPanic)
+	time.Sleep(time.Second)
+	// output:
+	// github.com/modern-go/concurrent_test.willPanic
+}
+
+func willPanic(ctx context.Context) {
+	panic("!!!")
+}
diff --git a/vendor/github.com/modern-go/reflect2/.travis.yml b/vendor/github.com/modern-go/reflect2/.travis.yml
new file mode 100644
index 000000000..fbb43744d
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+
+go:
+  - 1.8.x
+  - 1.x
+
+before_install:
+  - go get -t -v ./...
+  - go get -t -v github.com/modern-go/reflect2-tests/...
+
+script:
+  - ./test.sh
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.lock b/vendor/github.com/modern-go/reflect2/Gopkg.lock
new file mode 100644
index 000000000..2a3a69893
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/Gopkg.lock
@@ -0,0 +1,15 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+  name = "github.com/modern-go/concurrent"
+  packages = ["."]
+  revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a"
+  version = "1.0.0"
+
+[solve-meta]
+  analyzer-name = "dep"
+  analyzer-version = 1
+  inputs-digest = "daee8a88b3498b61c5640056665b8b9eea062006f5e596bbb6a3ed9119a11ec7"
+  solver-name = "gps-cdcl"
+  solver-version = 1
diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.toml b/vendor/github.com/modern-go/reflect2/Gopkg.toml
new file mode 100644
index 000000000..2f4f4dbdc
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/Gopkg.toml
@@ -0,0 +1,35 @@
+# Gopkg.toml example
+#
+# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
+# 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"
+#
+# [prune]
+#   non-go = false
+#   go-tests = true
+#   unused-packages = true
+
+ignored = []
+
+[[constraint]]
+  name = "github.com/modern-go/concurrent"
+  version = "1.0.0"
+
+[prune]
+  go-tests = true
+  unused-packages = true
diff --git a/vendor/github.com/modern-go/reflect2/LICENSE b/vendor/github.com/modern-go/reflect2/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/LICENSE
@@ -0,0 +1,201 @@
+                                 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/README.md b/vendor/github.com/modern-go/reflect2/README.md
new file mode 100644
index 000000000..6f968aab9
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/README.md
@@ -0,0 +1,71 @@
+# reflect2
+
+[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/reflect2/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/reflect2?badge)
+[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/reflect2)
+[![Build Status](https://travis-ci.org/modern-go/reflect2.svg?branch=master)](https://travis-ci.org/modern-go/reflect2)
+[![codecov](https://codecov.io/gh/modern-go/reflect2/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/reflect2)
+[![rcard](https://goreportcard.com/badge/github.com/modern-go/reflect2)](https://goreportcard.com/report/github.com/modern-go/reflect2)
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/reflect2/master/LICENSE)
+
+reflect api that avoids runtime reflect.Value cost
+
+* reflect get/set interface{}, with type checking
+* reflect get/set unsafe.Pointer, without type checking
+* `reflect2.TypeByName` works like `Class.forName` found in java
+
+[json-iterator](https://github.com/json-iterator/go) use this package to save runtime dispatching cost.
+This package is designed for low level libraries to optimize reflection performance.
+General application should still use reflect standard library.
+
+# reflect2.TypeByName
+
+```go
+// given package is github.com/your/awesome-package
+type MyStruct struct {
+	// ...
+}
+
+// will return the type
+reflect2.TypeByName("awesome-package.MyStruct")
+// however, if the type has not been used
+// it will be eliminated by compiler, so we can not get it in runtime
+```
+
+# reflect2 get/set interface{}
+
+```go
+valType := reflect2.TypeOf(1)
+i := 1
+j := 10
+valType.Set(&i, &j)
+// i will be 10
+```
+
+to get set `type`, always use its pointer `*type`
+
+# reflect2 get/set unsafe.Pointer
+
+```go
+valType := reflect2.TypeOf(1)
+i := 1
+j := 10
+valType.UnsafeSet(unsafe.Pointer(&i), unsafe.Pointer(&j))
+// i will be 10
+```
+
+to get set `type`, always use its pointer `*type`
+
+# benchmark
+
+Benchmark is not necessary for this package. It does nothing actually.
+As it is just a thin wrapper to make go runtime public. 
+Both `reflect2` and `reflect` call same function 
+provided by `runtime` package exposed by go language.
+
+# unsafe safety
+
+Instead of casting `[]byte` to `sliceHeader` in your application using unsafe.
+We can use reflect2 instead. This way, if `sliceHeader` changes in the future,
+only reflect2 need to be upgraded.
+
+reflect2 tries its best to keep the implementation same as reflect (by testing).
\ No newline at end of file
diff --git a/vendor/github.com/modern-go/reflect2/go_above_17.go b/vendor/github.com/modern-go/reflect2/go_above_17.go
new file mode 100644
index 000000000..5c1cea868
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/go_above_17.go
@@ -0,0 +1,8 @@
+//+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
new file mode 100644
index 000000000..c7e3b7801
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/go_above_19.go
@@ -0,0 +1,14 @@
+//+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
new file mode 100644
index 000000000..65a93c889
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/go_below_17.go
@@ -0,0 +1,9 @@
+//+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
new file mode 100644
index 000000000..b050ef70c
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/go_below_19.go
@@ -0,0 +1,14 @@
+//+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
new file mode 100644
index 000000000..63b49c799
--- /dev/null
+++ b/vendor/github.com/modern-go/reflect2/reflect2.go
@@ -0,0 +1,298 @@
+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 {

  (This diff was longer than 20,000 lines, and has been truncated...)


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services