Repository: prebid/prebid-server
Pull request #1887 (2021-06-09 22:21:34)

Unit test random map order fix


Patch:
diff --git a/adapters/e_volution/evolution.go b/adapters/e_volution/evolution.go
new file mode 100644
index 00000000..26df301c
--- /dev/null
+++ b/adapters/e_volution/evolution.go
@@ -0,0 +1,112 @@
+package evolution
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/mxmCherry/openrtb/v15/openrtb2"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/errortypes"
+	"github.com/prebid/prebid-server/openrtb_ext"
+	"net/http"
+)
+
+type adapter struct {
+	URI string
+}
+
+type bidExt struct {
+	MediaType openrtb_ext.BidType `json:"mediaType"`
+}
+
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+	bidder := &adapter{
+		URI: config.Endpoint,
+	}
+	return bidder, nil
+}
+
+func (a *adapter) MakeRequests(
+	openRTBRequest *openrtb2.BidRequest,
+	reqInfo *adapters.ExtraRequestInfo,
+) (
+	requestsToBidder []*adapters.RequestData,
+	errs []error,
+) {
+
+	reqJSON, err := json.Marshal(openRTBRequest)
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	headers := http.Header{}
+	headers.Add("Content-Type", "application/json;charset=utf-8")
+	headers.Add("Accept", "application/json")
+
+	return []*adapters.RequestData{{
+		Method:  http.MethodPost,
+		Body:    reqJSON,
+		Uri:     a.URI,
+		Headers: headers,
+	}}, nil
+}
+
+func (a *adapter) MakeBids(
+	openRTBRequest *openrtb2.BidRequest,
+	requestToBidder *adapters.RequestData,
+	bidderRawResponse *adapters.ResponseData,
+) (
+	bidderResponse *adapters.BidderResponse,
+	errs []error,
+) {
+	if bidderRawResponse.StatusCode == http.StatusNoContent {
+		return nil, nil
+	}
+
+	if bidderRawResponse.StatusCode == http.StatusBadRequest {
+		return nil, []error{&errortypes.BadInput{
+			Message: fmt.Sprintf("Bad Request. %s", string(bidderRawResponse.Body)),
+		}}
+	}
+
+	if bidderRawResponse.StatusCode == http.StatusServiceUnavailable {
+		return nil, nil
+	}
+
+	if bidderRawResponse.StatusCode != http.StatusOK {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Something went wrong, please contact your Account Manager. Status Code: [ %d ] ", bidderRawResponse.StatusCode),
+		}}
+	}
+
+	responseBody := bidderRawResponse.Body
+	var bidResp openrtb2.BidResponse
+	if err := json.Unmarshal(responseBody, &bidResp); err != nil {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Bad response, %s", err),
+		}}
+	}
+
+	if len(bidResp.SeatBid) == 0 {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Empty seatbid"),
+		}}
+	}
+
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid))
+	sb := bidResp.SeatBid[0]
+	for i := range sb.Bid {
+		var bidType openrtb_ext.BidType
+		var bidExt bidExt
+		if err := json.Unmarshal(sb.Bid[i].Ext, &bidExt); err != nil {
+			bidType = openrtb_ext.BidTypeBanner
+		} else {
+			bidType = bidExt.MediaType
+		}
+		bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
+			Bid:     &sb.Bid[i],
+			BidType: bidType,
+		})
+	}
+	return bidResponse, nil
+}
diff --git a/adapters/e_volution/usersync.go b/adapters/e_volution/usersync.go
new file mode 100644
index 00000000..f22784d0
--- /dev/null
+++ b/adapters/e_volution/usersync.go
@@ -0,0 +1,12 @@
+package evolution
+
+import (
+	"text/template"
+
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/usersync"
+)
+
+func NewEvolutionSyncer(temp *template.Template) usersync.Usersyncer {
+	return adapters.NewSyncer("e_volution", temp, adapters.SyncTypeRedirect)
+}
diff --git a/adapters/lifestreet/lifestreet.go b/adapters/lifestreet/lifestreet.go
deleted file mode 100644
index 14f69317..00000000
--- a/adapters/lifestreet/lifestreet.go
+++ /dev/null
@@ -1,219 +0,0 @@
-package lifestreet
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"strings"
-
-	"github.com/mxmCherry/openrtb/v15/openrtb2"
-	"github.com/prebid/prebid-server/openrtb_ext"
-
-	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/errortypes"
-	"github.com/prebid/prebid-server/pbs"
-	"golang.org/x/net/context/ctxhttp"
-)
-
-type LifestreetAdapter struct {
-	http *adapters.HTTPAdapter
-	URI  string
-}
-
-// used for cookies and such
-func (a *LifestreetAdapter) Name() string {
-	return "lifestreet"
-}
-
-func (a *LifestreetAdapter) SkipNoCookies() bool {
-	return false
-}
-
-// parameters for Lifestreet adapter.
-type lifestreetParams struct {
-	SlotTag string `json:"slot_tag"`
-}
-
-func (a *LifestreetAdapter) callOne(ctx context.Context, req *pbs.PBSRequest, reqJSON bytes.Buffer) (result adapters.CallOneResult, err error) {
-	httpReq, err := http.NewRequest("POST", a.URI, &reqJSON)
-	httpReq.Header.Add("Content-Type", "application/json;charset=utf-8")
-	httpReq.Header.Add("Accept", "application/json")
-
-	lsmResp, e := ctxhttp.Do(ctx, a.http.Client, httpReq)
-	if e != nil {
-		err = e
-		return
-	}
-
-	defer lsmResp.Body.Close()
-	body, _ := ioutil.ReadAll(lsmResp.Body)
-	result.ResponseBody = string(body)
-
-	result.StatusCode = lsmResp.StatusCode
-
-	if lsmResp.StatusCode == 204 {
-		return
-	}
-
-	if lsmResp.StatusCode != 200 {
-		err = fmt.Errorf("HTTP status %d; body: %s", lsmResp.StatusCode, result.ResponseBody)
-		return
-	}
-
-	var bidResp openrtb2.BidResponse
-	err = json.Unmarshal(body, &bidResp)
-	if err != nil {
-		return
-	}
-	if len(bidResp.SeatBid) == 0 || len(bidResp.SeatBid[0].Bid) == 0 {
-		return
-	}
-	bid := bidResp.SeatBid[0].Bid[0]
-
-	t := openrtb_ext.BidTypeBanner
-
-	if bid.Ext != nil {
-		var e openrtb_ext.ExtBid
-		err = json.Unmarshal(bid.Ext, &e)
-		if err != nil {
-			return
-		}
-		t = e.Prebid.Type
-	}
-
-	result.Bid = &pbs.PBSBid{
-		AdUnitCode:        bid.ImpID,
-		Price:             bid.Price,
-		Adm:               bid.AdM,
-		Creative_id:       bid.CrID,
-		Width:             bid.W,
-		Height:            bid.H,
-		DealId:            bid.DealID,
-		NURL:              bid.NURL,
-		CreativeMediaType: string(t),
-	}
-	return
-}
-
-func (a *LifestreetAdapter) MakeOpenRtbBidRequest(req *pbs.PBSRequest, bidder *pbs.PBSBidder, slotTag string, mtype pbs.MediaType, unitInd int) (openrtb2.BidRequest, error) {
-	lsReq, err := adapters.MakeOpenRTBGeneric(req, bidder, a.Name(), []pbs.MediaType{mtype})
-
-	if err != nil {
-		return openrtb2.BidRequest{}, err
-	}
-
-	if lsReq.Imp != nil && len(lsReq.Imp) > 0 {
-		lsReq.Imp = lsReq.Imp[unitInd : unitInd+1]
-
-		if lsReq.Imp[0].Banner != nil {
-			lsReq.Imp[0].Banner.Format = nil
-		}
-		lsReq.Imp[0].TagID = slotTag
-
-		return lsReq, nil
-	} else {
-		return lsReq, &errortypes.BadInput{
-			Message: "No supported impressions",
-		}
-	}
-}
-
-func (a *LifestreetAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder *pbs.PBSBidder) (pbs.PBSBidSlice, error) {
-	requests := make([]bytes.Buffer, len(bidder.AdUnits)*2)
-	reqIndex := 0
-	for i, unit := range bidder.AdUnits {
-		var params lifestreetParams
-		err := json.Unmarshal(unit.Params, &params)
-		if err != nil {
-			return nil, err
-		}
-		if params.SlotTag == "" {
-			return nil, &errortypes.BadInput{
-				Message: "Missing slot_tag param",
-			}
-		}
-		s := strings.Split(params.SlotTag, ".")
-		if len(s) != 2 {
-			return nil, &errortypes.BadInput{
-				Message: fmt.Sprintf("Invalid slot_tag param '%s'", params.SlotTag),
-			}
-		}
-
-		// BANNER
-		lsReqB, err := a.MakeOpenRtbBidRequest(req, bidder, params.SlotTag, pbs.MEDIA_TYPE_BANNER, i)
-		if err == nil {
-			err = json.NewEncoder(&requests[reqIndex]).Encode(lsReqB)
-			reqIndex = reqIndex + 1
-			if err != nil {
-				return nil, err
-			}
-		}
-
-		// VIDEO
-		lsReqV, err := a.MakeOpenRtbBidRequest(req, bidder, params.SlotTag, pbs.MEDIA_TYPE_VIDEO, i)
-		if err == nil {
-			err = json.NewEncoder(&requests[reqIndex]).Encode(lsReqV)
-			reqIndex = reqIndex + 1
-			if err != nil {
-				return nil, err
-			}
-		}
-	}
-
-	ch := make(chan adapters.CallOneResult)
-	for i := range bidder.AdUnits {
-		go func(bidder *pbs.PBSBidder, reqJSON bytes.Buffer) {
-			result, err := a.callOne(ctx, req, reqJSON)
-			result.Error = err
-			if result.Bid != nil {
-				result.Bid.BidderCode = bidder.BidderCode
-				result.Bid.BidID = bidder.LookupBidID(result.Bid.AdUnitCode)
-				if result.Bid.BidID == "" {
-					result.Error = &errortypes.BadServerResponse{
-						Message: fmt.Sprintf("Unknown ad unit code '%s'", result.Bid.AdUnitCode),
-					}
-					result.Bid = nil
-				}
-			}
-			ch <- result
-		}(bidder, requests[i])
-	}
-
-	var err error
-
-	bids := make(pbs.PBSBidSlice, 0)
-	for i := 0; i < len(bidder.AdUnits); i++ {
-		result := <-ch
-		if result.Bid != nil {
-			bids = append(bids, result.Bid)
-		}
-		if req.IsDebug {
-			debug := &pbs.BidderDebug{
-				RequestURI:   a.URI,
-				RequestBody:  requests[i].String(),
-				StatusCode:   result.StatusCode,
-				ResponseBody: result.ResponseBody,
-			}
-			bidder.Debug = append(bidder.Debug, debug)
-		}
-		if result.Error != nil {
-			err = result.Error
-		}
-	}
-
-	if len(bids) == 0 {
-		return nil, err
-	}
-	return bids, nil
-}
-
-func NewLifestreetLegacyAdapter(config *adapters.HTTPAdapterConfig, endpoint string) *LifestreetAdapter {
-	a := adapters.NewHTTPAdapter(config)
-	return &LifestreetAdapter{
-		http: a,
-		URI:  endpoint,
-	}
-}
diff --git a/adapters/lifestreet/usersync.go b/adapters/lifestreet/usersync.go
deleted file mode 100644
index f5300eba..00000000
--- a/adapters/lifestreet/usersync.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package lifestreet
-
-import (
-	"text/template"
-
-	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/usersync"
-)
-
-func NewLifestreetSyncer(temp *template.Template) usersync.Usersyncer {
-	return adapters.NewSyncer("lifestreet", temp, adapters.SyncTypeRedirect)
-}
diff --git a/config/config.go b/config/config.go
index f6250be6..a259a9aa 100644
--- a/config/config.go
+++ b/config/config.go
@@ -604,6 +604,7 @@ func (cfg *Configuration) setDerivedDefaults() {
 	// openrtb_ext.BidderDMX doesn't have a good default.
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderDeepintent, "https://match.deepintent.com/usersync/136?id=unk&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Ddeepintent%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BUID%5D")
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEmxDigital, "https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID")
+	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEVolution, "https://sync.e-volution.ai/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3De_volution%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BUID%5D")
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEngageBDR, "https://match.bnmla.com/usersync/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dengagebdr%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D")
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEPlanning, "https://ads.us.e-planning.net/uspd/1/?du="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Deplanning%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
 	// openrtb_ext.BidderEpom doesn't have a good default.
@@ -617,7 +618,6 @@ func (cfg *Configuration) setDerivedDefaults() {
 	// openrtb_ext.BidderInvibes doesn't have a good default.
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderJixie, "https://id.jixie.io/api/sync?pid=&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Djixie%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%25%25JXUID%25%25")
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderKrushmedia, "https://cs.krushmedia.com/4e4abdd5ecc661643458a730b1aa927d.gif?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dkrushmedia%26uid%3D%5BUID%5D")
-	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderLifestreet, "https://ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dlifestreet%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%24visitor_cookie%24%24")
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderLockerDome, "https://lockerdome.com/usync/prebidserver?pid="+cfg.Adapters["lockerdome"].PlatformID+"&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7B%7Buid%7D%7D")
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderLogicad, "https://cr-p31.ladsp.jp/cookiesender/31?r=true&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ru="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dlogicad%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
 	setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderLunaMedia, "https://api.lunamedia.io/xp/user-sync?redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dlunamedia%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
@@ -863,6 +863,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.eplanning.endpoint", "http://rtb.e-planning.net/pbs/1")
 	v.SetDefault("adapters.epom.endpoint", "https://an.epom.com/ortb")
 	v.SetDefault("adapters.epom.disabled", true)
+	v.SetDefault("adapters.e_volution.endpoint", "http://service.e-volution.ai/pbserver")
 	v.SetDefault("adapters.gamma.endpoint", "https://hb.gammaplatform.com/adx/request/")
 	v.SetDefault("adapters.gamoshi.endpoint", "https://rtb.gamoshi.io")
 	v.SetDefault("adapters.grid.endpoint", "https://grid.bidswitch.net/sp_bid?sp=prebid")
@@ -877,7 +878,6 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.invibes.endpoint", "https://{{.Host}}/bid/ServerBidAdContent")
 	v.SetDefault("adapters.kidoz.endpoint", "http://prebid-adapter.kidoz.net/openrtb2/auction?src=prebid-server")
 	v.SetDefault("adapters.kubient.endpoint", "https://kssp.kbntx.ch/prebid")
-	v.SetDefault("adapters.lifestreet.endpoint", "https://prebid.s2s.lfstmedia.com/adrequest")
 	v.SetDefault("adapters.lockerdome.endpoint", "https://lockerdome.com/ladbid/prebidserver/openrtb2")
 	v.SetDefault("adapters.logicad.endpoint", "https://pbs.ladsp.com/adrequest/prebidserver")
 	v.SetDefault("adapters.lunamedia.endpoint", "http://api.lunamedia.io/xp/get?pubid={{.PublisherID}}")
diff --git a/endpoints/auction.go b/endpoints/auction.go
index 069abfec..f76f8237 100644
--- a/endpoints/auction.go
+++ b/endpoints/auction.go
@@ -146,6 +146,8 @@ func (a *auction) auction(w http.ResponseWriter, r *http.Request, _ httprouter.P
 
 			go bidderRunner(bidder, blabels)
 
+		} else if bidder.BidderCode == "lifestreet" {
+			bidder.Error = "Bidder is no longer available"
 		} else {
 			bidder.Error = "Unsupported bidder"
 		}
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 4965f7f5..a773d268 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -46,6 +46,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/decenterads"
 	"github.com/prebid/prebid-server/adapters/deepintent"
 	"github.com/prebid/prebid-server/adapters/dmx"
+	"github.com/prebid/prebid-server/adapters/e_volution"
 	"github.com/prebid/prebid-server/adapters/emx_digital"
 	"github.com/prebid/prebid-server/adapters/engagebdr"
 	"github.com/prebid/prebid-server/adapters/eplanning"
@@ -169,6 +170,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderEngageBDR:         engagebdr.Builder,
 		openrtb_ext.BidderEPlanning:         eplanning.Builder,
 		openrtb_ext.BidderEpom:              epom.Builder,
+		openrtb_ext.BidderEVolution:         evolution.Builder,
 		openrtb_ext.BidderGamma:             gamma.Builder,
 		openrtb_ext.BidderGamoshi:           gamoshi.Builder,
 		openrtb_ext.BidderGrid:              grid.Builder,
diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go
index 8af6d11a..9ab27561 100644
--- a/exchange/adapter_util.go
+++ b/exchange/adapter_util.go
@@ -4,33 +4,13 @@ import (
 	"fmt"
 	"net/http"
 
-	"github.com/prebid/prebid-server/metrics"
-
 	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/adapters/lifestreet"
 	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/metrics"
 	"github.com/prebid/prebid-server/openrtb_ext"
 )
 
 func BuildAdapters(client *http.Client, cfg *config.Configuration, infos config.BidderInfos, me metrics.MetricsEngine) (map[openrtb_ext.BidderName]adaptedBidder, []error) {
-	exchangeBidders := buildExchangeBiddersLegacy(cfg.Adapters, infos)
-
-	exchangeBiddersModern, errs := buildExchangeBidders(cfg, infos, client, me)
-	if len(errs) > 0 {
-		return nil, errs
-	}
-
-	// Merge legacy and modern bidders, giving priority to the modern bidders.
-	for bidderName, bidder := range exchangeBiddersModern {
-		exchangeBidders[bidderName] = bidder
-	}
-
-	wrapWithMiddleware(exchangeBidders)
-
-	return exchangeBidders, nil
-}
-
-func buildExchangeBidders(cfg *config.Configuration, infos config.BidderInfos, client *http.Client, me metrics.MetricsEngine) (map[openrtb_ext.BidderName]adaptedBidder, []error) {
 	bidders, errs := buildBidders(cfg.Adapters, infos, newAdapterBuilders())
 	if len(errs) > 0 {
 		return nil, errs
@@ -38,16 +18,12 @@ func buildExchangeBidders(cfg *config.Configuration, infos config.BidderInfos, c
 
 	exchangeBidders := make(map[openrtb_ext.BidderName]adaptedBidder, len(bidders))
 	for bidderName, bidder := range bidders {
-		info, infoFound := infos[string(bidderName)]
-		if !infoFound {
-			errs = append(errs, fmt.Errorf("%v: bidder info not found", bidder))
-			continue
-		}
-		exchangeBidders[bidderName] = adaptBidder(bidder, client, cfg, me, bidderName, info.Debug)
+		info := infos[string(bidderName)]
+		exchangeBidder := adaptBidder(bidder, client, cfg, me, bidderName, info.Debug)
+		exchangeBidder = addValidatedBidderMiddleware(exchangeBidder)
+		exchangeBidders[bidderName] = exchangeBidder
 	}
-
 	return exchangeBidders, nil
-
 }
 
 func buildBidders(adapterConfig map[string]config.Adapter, infos config.BidderInfos, builders map[openrtb_ext.BidderName]adapters.Builder) (map[openrtb_ext.BidderName]adapters.Bidder, []error) {
@@ -61,11 +37,6 @@ func buildBidders(adapterConfig map[string]config.Adapter, infos config.BidderIn
 			continue
 		}
 
-		// Ignore Legacy Bidders
-		if bidderName == openrtb_ext.BidderLifestreet {
-			continue
-		}
-
 		info, infoFound := infos[string(bidderName)]
 		if !infoFound {
 			errs = append(errs, fmt.Errorf("%v: bidder info not found", bidder))
@@ -84,34 +55,13 @@ func buildBidders(adapterConfig map[string]config.Adapter, infos config.BidderIn
 				errs = append(errs, fmt.Errorf("%v: %v", bidder, builderErr))
 				continue
 			}
-
-			bidderWithInfoEnforcement := adapters.BuildInfoAwareBidder(bidderInstance, info)
-
-			bidders[bidderName] = bidderWithInfoEnforcement
+			bidders[bidderName] = adapters.BuildInfoAwareBidder(bidderInstance, info)
 		}
 	}
 
 	return bidders, errs
 }
 
-func buildExchangeBiddersLegacy(adapterConfig map[string]config.Adapter, infos config.BidderInfos) map[openrtb_ext.BidderName]adaptedBidder {
-	bidders := make(map[openrtb_ext.BidderName]adaptedBidder, 2)
-
-	// Lifestreet
-	if infos[string(openrtb_ext.BidderLifestreet)].Enabled {
-		adapter := lifestreet.NewLifestreetLegacyAdapter(adapters.DefaultHTTPAdapterConfig, adapterConfig[string(openrtb_ext.BidderLifestreet)].Endpoint)
-		bidders[openrtb_ext.BidderLifestreet] = adaptLegacyAdapter(adapter)
-	}
-
-	return bidders
-}
-
-func wrapWithMiddleware(bidders map[openrtb_ext.BidderName]adaptedBidder) {
-	for name, bidder := range bidders {
-		bidders[name] = addValidatedBidderMiddleware(bidder)
-	}
-}
-
 // GetActiveBidders returns a map of all active bidder names.
 func GetActiveBidders(infos config.BidderInfos) map[string]openrtb_ext.BidderName {
 	activeBidders := make(map[string]openrtb_ext.BidderName)
@@ -127,7 +77,9 @@ func GetActiveBidders(infos config.BidderInfos) map[string]openrtb_ext.BidderNam
 
 // GetDisabledBiddersErrorMessages returns a map of error messages for disabled bidders.
 func GetDisabledBiddersErrorMessages(infos config.BidderInfos) map[string]string {
-	disabledBidders := make(map[string]string)
+	disabledBidders := map[string]string{
+		"lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
+	}
 
 	for name, info := range infos {
 		if !info.Enabled {
diff --git a/exchange/legacy.go b/exchange/legacy.go
deleted file mode 100644
index 3983ce13..00000000
--- a/exchange/legacy.go
+++ /dev/null
@@ -1,366 +0,0 @@
-package exchange
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-
-	"github.com/buger/jsonparser"
-	"github.com/mxmCherry/openrtb/v15/openrtb2"
-	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/currency"
-	"github.com/prebid/prebid-server/openrtb_ext"
-	"github.com/prebid/prebid-server/pbs"
-	"github.com/prebid/prebid-server/usersync"
-)
-
-// AdaptLegacyAdapter turns a bidder.Adapter into an adaptedBidder.
-//
-// This is a temporary function which helps make the transition to OpenRTB smooth. Bidders which have not been
-// updated yet can use this to be "OpenRTB-ish". They'll bid as well as they can, given the limitations of the
-// legacy protocol
-func adaptLegacyAdapter(adapter adapters.Adapter) adaptedBidder {
-	return &adaptedAdapter{
-		adapter: adapter,
-	}
-}
-
-type adaptedAdapter struct {
-	adapter adapters.Adapter
-}
-
-// requestBid attempts to bid on OpenRTB requests using the legacy protocol.
-//
-// This is not ideal. OpenRTB provides a superset of the legacy data structures.
-// For requests which use those features, the best we can do is respond with "no bid".
-func (bidder *adaptedAdapter) requestBid(ctx context.Context, request *openrtb2.BidRequest, name openrtb_ext.BidderName, bidAdjustment float64, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, accountDebugAllowed bool) (*pbsOrtbSeatBid, []error) {
-	legacyRequest, legacyBidder, errs := bidder.toLegacyAdapterInputs(request, name)
-	if legacyRequest == nil || legacyBidder == nil {
-		return nil, errs
-	}
-
-	legacyBids, err := bidder.adapter.Call(ctx, legacyRequest, legacyBidder)
-	if err != nil {
-		errs = append(errs, err)
-	}
-
-	for i := 0; i < len(legacyBids); i++ {
-		legacyBids[i].Price = legacyBids[i].Price * bidAdjustment
-	}
-
-	finalResponse, moreErrs := toNewResponse(legacyBids, legacyBidder, name)
-	return finalResponse, append(errs, moreErrs...)
-}
-
-// ----------------------------------------------------------------------------
-// Request transformations.
-
-// toLegacyAdapterInputs is a best-effort transformation of an OpenRTB BidRequest into the args needed to run a legacy Adapter.
-// If the OpenRTB request is too complex, it fails with an error.
-// If the error is nil, then the PBSRequest and PBSBidder are valid.
-func (bidder *adaptedAdapter) toLegacyAdapterInputs(req *openrtb2.BidRequest, name openrtb_ext.BidderName) (*pbs.PBSRequest, *pbs.PBSBidder, []error) {
-	legacyReq, err := bidder.toLegacyRequest(req)
-	if err != nil {
-		return nil, nil, []error{err}
-	}
-
-	legacyBidder, errs := toLegacyBidder(req, name)
-	if legacyBidder == nil {
-		return nil, nil, errs
-	}
-
-	return legacyReq, legacyBidder, errs
-}
-
-func (bidder *adaptedAdapter) toLegacyRequest(req *openrtb2.BidRequest) (*pbs.PBSRequest, error) {
-	acctId, err := toAccountId(req)
-	if err != nil {
-		return nil, err
-	}
-
-	tId, err := toTransactionId(req)
-	if err != nil {
-		return nil, err
-	}
-
-	isSecure, err := toSecure(req)
-	if err != nil {
-		return nil, err
-	}
-
-	isDebug := false
-	if req.Test == 1 {
-		isDebug = true
-	}
-
-	url := ""
-	domain := ""
-	if req.Site != nil {
-		url = req.Site.Page
-		domain = req.Site.Domain
-	}
-
-	cookie := usersync.NewPBSCookie()
-	if req.User != nil {
-		if req.User.BuyerUID != "" {
-			cookie.TrySync(bidder.adapter.Name(), req.User.BuyerUID)
-		}
-
-		// This shouldn't be appnexus-specific... but this line does correctly invert the
-		// logic from adapters/openrtb_util.go, which will preserve this questionable behavior in legacy adapters.
-		if req.User.ID != "" {
-			cookie.TrySync("adnxs", req.User.ID)
-		}
-	}
-
-	return &pbs.PBSRequest{
-		AccountID: acctId,
-		Tid:       tId,
-		// CacheMarkup is excluded because no legacy adapters read from it
-		// SortBids is excluded because no legacy adapters read from it
-		// MaxKeyLength is excluded because no legacy adapters read from it
-		Secure:        isSecure,
-		TimeoutMillis: req.TMax,
-		// AdUnits is excluded because no legacy adapters read from it
-		IsDebug: isDebug,
-		App:     req.App,
-		Device:  req.Device,
-		// PBSUser is excluded because rubicon is the only adapter which reads from it, and they're supporting OpenRTB directly
-		// SDK is excluded because that information doesn't exist in openrtb2.
-		// Bidders is excluded because no legacy adapters read from it
-		User:   req.User,
-		Cookie: cookie,
-		Url:    url,
-		Domain: domain,
-		// Start is excluded because no legacy adapters read from it
-		Regs: req.Regs,
-	}, nil
-}
-
-func toAccountId(req *openrtb2.BidRequest) (string, error) {
-	if req.Site != nil && req.Site.Publisher != nil {
-		return req.Site.Publisher.ID, nil
-	}
-	if req.App != nil && req.App.Publisher != nil {
-		return req.App.Publisher.ID, nil
-	}
-	return "", errors.New("bidrequest.site.publisher.id or bidrequest.app.publisher.id required for legacy bidders.")
-}
-
-func toTransactionId(req *openrtb2.BidRequest) (string, error) {
-	if req.Source != nil {
-		return req.Source.TID, nil
-	}
-	return "", errors.New("bidrequest.source.tid required for legacy bidders.")
-}
-
-func toSecure(req *openrtb2.BidRequest) (secure int8, err error) {
-	secure = -1
-	for _, imp := range req.Imp {
-		if imp.Secure != nil {
-			thisVal := *imp.Secure
-			if thisVal == 0 {
-				if secure == 1 {
-					err = errors.New("bidrequest.imp[i].secure must be consistent for legacy bidders. Mixing 0 and 1 are not allowed.")
-					return
-				}
-				secure = 0
-			} else if thisVal == 1 {
-				if secure == 0 {
-					err = errors.New("bidrequest.imp[i].secure must be consistent for legacy bidders. Mixing 0 and 1 are not allowed.")
-					return
-				}
-				secure = 1
-			}
-		}
-	}
-	if secure == -1 {
-		secure = 0
-	}
-
-	return
-}
-
-func toLegacyBidder(req *openrtb2.BidRequest, name openrtb_ext.BidderName) (*pbs.PBSBidder, []error) {
-	adUnits, errs := toPBSAdUnits(req)
-	if len(adUnits) > 0 {
-		return &pbs.PBSBidder{
-			BidderCode: string(name),
-			// AdUnitCode is excluded because no legacy adapters read from it
-			// ResponseTime is excluded because no legacy adapters read from it
-			// NumBids is excluded because no legacy adapters read from it
-			// Error is excluded because no legacy adapters read from it
-			// NoCookie is excluded because no legacy adapters read from it
-			// NoBid is excluded because no legacy adapters read from it
-			// UsersyncInfo is excluded because no legacy adapters read from it
-			// Debug is excluded because legacy adapters only use it in nil-safe ways.
-			//   They *do* write to it, though, so it may be read when unpacking the response.
-			AdUnits: adUnits,
-		}, errs
-	} else {
-		return nil, errs
-	}
-}
-
-func toPBSAdUnits(req *openrtb2.BidRequest) ([]pbs.PBSAdUnit, []error) {
-	adUnits := make([]pbs.PBSAdUnit, len(req.Imp))
-	var errs []error = nil
-	nextAdUnit := 0
-	for i := 0; i < len(req.Imp); i++ {
-		err := initPBSAdUnit(&(req.Imp[i]), &(adUnits[nextAdUnit]))
-		if err != nil {
-			errs = append(errs, err)
-		} else {
-			nextAdUnit++
-		}
-	}
-	return adUnits[:nextAdUnit], errs
-}
-
-func initPBSAdUnit(imp *openrtb2.Imp, adUnit *pbs.PBSAdUnit) error {
-	var sizes []openrtb2.Format = nil
-
-	video := pbs.PBSVideo{}
-	if imp.Video != nil {
-		video.Mimes = imp.Video.MIMEs
-		video.Minduration = imp.Video.MinDuration
-		video.Maxduration = imp.Video.MaxDuration
-		if imp.Video.StartDelay != nil {
-			video.Startdelay = int64(*imp.Video.StartDelay)
-		}
-		if imp.Video.Skip != nil {
-			video.Skippable = int(*imp.Video.Skip)
-		}
-		if len(imp.Video.PlaybackMethod) == 1 {
-			video.PlaybackMethod = int8(imp.Video.PlaybackMethod[0])
-		}
-		if len(imp.Video.Protocols) > 0 {
-			video.Protocols = make([]int8, len(imp.Video.Protocols))
-			for i := 0; i < len(imp.Video.Protocols); i++ {
-				video.Protocols[i] = int8(imp.Video.Protocols[i])
-			}
-		}
-		// Fixes #360
-		if imp.Video.W != 0 && imp.Video.H != 0 {
-			sizes = append(sizes, openrtb2.Format{
-				W: imp.Video.W,
-				H: imp.Video.H,
-			})
-		}
-	}
-	topFrame := int8(0)
-	if imp.Banner != nil {
-		topFrame = imp.Banner.TopFrame
-		sizes = append(sizes, imp.Banner.Format...)
-	}
-
-	params, _, _, err := jsonparser.Get(imp.Ext, "bidder")
-	if err != nil {
-		return err
-	}
-
-	mediaTypes := make([]pbs.MediaType, 0, 2)
-	if imp.Banner != nil {
-		mediaTypes = append(mediaTypes, pbs.MEDIA_TYPE_BANNER)
-	}
-	if imp.Video != nil {
-		mediaTypes = append(mediaTypes, pbs.MEDIA_TYPE_VIDEO)
-	}
-	if len(mediaTypes) == 0 {
-		return errors.New("legacy bidders can only bid on banner and video ad units")
-	}
-
-	adUnit.Sizes = sizes
-	adUnit.TopFrame = topFrame
-	adUnit.Code = imp.ID
-	adUnit.BidID = imp.ID
-	adUnit.Params = json.RawMessage(params)
-	adUnit.Video = video
-	adUnit.MediaTypes = mediaTypes
-	adUnit.Instl = imp.Instl
-
-	return nil
-}
-
-// ----------------------------------------------------------------------------
-// Response transformations.
-
-// toNewResponse is a best-effort transformation of legacy Bids into an OpenRTB response.
-func toNewResponse(bids pbs.PBSBidSlice, bidder *pbs.PBSBidder, name openrtb_ext.BidderName) (*pbsOrtbSeatBid, []error) {
-	newBids, errs := transformBids(bids)
-	return &pbsOrtbSeatBid{
-		bids:      newBids,
-		httpCalls: transformDebugs(bidder.Debug),
-	}, errs
-}
-
-func transformBids(legacyBids pbs.PBSBidSlice) ([]*pbsOrtbBid, []error) {
-	newBids := make([]*pbsOrtbBid, 0, len(legacyBids))
-	var errs []error
-	for _, legacyBid := range legacyBids {
-		if legacyBid != nil {
-			newBid, err := transformBid(legacyBid)
-			if err == nil {
-				newBids = append(newBids, newBid)
-			} else {
-				errs = append(errs, err)
-			}
-		}
-	}
-	return newBids, errs
-}
-
-func transformBid(legacyBid *pbs.PBSBid) (*pbsOrtbBid, error) {
-	newBid := transformBidToOrtb(legacyBid)
-
-	newBidType, err := openrtb_ext.ParseBidType(legacyBid.CreativeMediaType)
-	if err != nil {
-		return nil, err
-	}
-
-	return &pbsOrtbBid{
-		bid:     newBid,
-		bidType: newBidType,
-	}, nil
-}
-
-func transformBidToOrtb(legacyBid *pbs.PBSBid) *openrtb2.Bid {
-	return &openrtb2.Bid{
-		ID:    legacyBid.BidID,
-		ImpID: legacyBid.AdUnitCode,
-		CrID:  legacyBid.Creative_id,
-		// legacyBid.CreativeMediaType is handled by transformBid(), because it doesn't exist on the openrtb2.Bid
-		// legacyBid.BidderCode is handled by the exchange, which already knows which bidder we are.
-		// legacyBid.BidHash is ignored, because it doesn't get sent in the response anyway
-		Price:  legacyBid.Price,
-		NURL:   legacyBid.NURL,
-		AdM:    legacyBid.Adm,
-		W:      legacyBid.Width,
-		H:      legacyBid.Height,
-		DealID: legacyBid.DealId,
-		// TODO #216: Support CacheID here
-		// TODO: #216: Support CacheURL here
-		// ResponseTime is handled by the exchange, since it doesn't exist in the OpenRTB Bid
-		// AdServerTargeting is handled by the exchange. Rubicon's adapter is the only one which writes to it,
-		//   but that doesn't matter since they're supporting OpenRTB directly.
-	}
-}
-
-func transformDebugs(legacyDebugs []*pbs.BidderDebug) []*openrtb_ext.ExtHttpCall {
-	newDebug := make([]*openrtb_ext.ExtHttpCall, 0, len(legacyDebugs))
-	for _, legacyDebug := range legacyDebugs {
-		if legacyDebug != nil {
-			newDebug = append(newDebug, transformDebug(legacyDebug))
-		}
-	}
-	return newDebug
-}
-
-func transformDebug(legacyDebug *pbs.BidderDebug) *openrtb_ext.ExtHttpCall {
-	return &openrtb_ext.ExtHttpCall{
-		Uri:          legacyDebug.RequestURI,
-		RequestBody:  legacyDebug.RequestBody,
-		ResponseBody: legacyDebug.ResponseBody,
-		Status:       legacyDebug.StatusCode,
-	}
-}
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index aa75985f..ea6c809f 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -121,6 +121,7 @@ const (
 	BidderEngageBDR         BidderName = "engagebdr"
 	BidderEPlanning         BidderName = "eplanning"
 	BidderEpom              BidderName = "epom"
+	BidderEVolution         BidderName = "e_volution"
 	BidderGamma             BidderName = "gamma"
 	BidderGamoshi           BidderName = "gamoshi"
 	BidderGrid              BidderName = "grid"
@@ -135,7 +136,6 @@ const (
 	BidderKidoz             BidderName = "kidoz"
 	BidderKrushmedia        BidderName = "krushmedia"
 	BidderKubient           BidderName = "kubient"
-	BidderLifestreet        BidderName = "lifestreet"
 	BidderLockerDome        BidderName = "lockerdome"
 	BidderLogicad           BidderName = "logicad"
 	BidderLunaMedia         BidderName = "lunamedia"
@@ -241,6 +241,7 @@ func CoreBidderNames() []BidderName {
 		BidderEngageBDR,
 		BidderEPlanning,
 		BidderEpom,
+		BidderEVolution,
 		BidderGamma,
 		BidderGamoshi,
 		BidderGrid,
@@ -255,7 +256,6 @@ func CoreBidderNames() []BidderName {
 		BidderKidoz,
 		BidderKrushmedia,
 		BidderKubient,
-		BidderLifestreet,
 		BidderLockerDome,
 		BidderLogicad,
 		BidderLunaMedia,
diff --git a/router/router.go b/router/router.go
index 3b51d073..e1c42699 100644
--- a/router/router.go
+++ b/router/router.go
@@ -23,7 +23,6 @@ import (
 	"github.com/prebid/prebid-server/adapters/appnexus"
 	"github.com/prebid/prebid-server/adapters/conversant"
 	"github.com/prebid/prebid-server/adapters/ix"
-	"github.com/prebid/prebid-server/adapters/lifestreet"
 	"github.com/prebid/prebid-server/adapters/pubmatic"
 	"github.com/prebid/prebid-server/adapters/pulsepoint"
 	"github.com/prebid/prebid-server/adapters/rubicon"
@@ -160,7 +159,6 @@ func newExchangeMap(cfg *config.Configuration) map[string]adapters.Adapter {
 		"pulsepoint": pulsepoint.NewPulsePointLegacyAdapter(adapters.DefaultHTTPAdapterConfig, cfg.Adapters[string(openrtb_ext.BidderPulsepoint)].Endpoint),
 		"rubicon": rubicon.NewRubiconLegacyAdapter(adapters.DefaultHTTPAdapterConfig, cfg.Adapters[string(openrtb_ext.BidderRubicon)].Endpoint,
 			cfg.Adapters[string(openrtb_ext.BidderRubicon)].XAPI.Username, cfg.Adapters[string(openrtb_ext.BidderRubicon)].XAPI.Password, cfg.Adapters[string(openrtb_ext.BidderRubicon)].XAPI.Tracker),
-		"lifestreet": lifestreet.NewLifestreetLegacyAdapter(adapters.DefaultHTTPAdapterConfig, cfg.Adapters[string(openrtb_ext.BidderLifestreet)].Endpoint),
 		"conversant": conversant.NewConversantLegacyAdapter(adapters.DefaultHTTPAdapterConfig, cfg.Adapters[string(openrtb_ext.BidderConversant)].Endpoint),
 		"adform":     adform.NewAdformLegacyAdapter(adapters.DefaultHTTPAdapterConfig, cfg.Adapters[string(openrtb_ext.BidderAdform)].Endpoint),
 		"sovrn":      sovrn.NewSovrnLegacyAdapter(adapters.DefaultHTTPAdapterConfig, cfg.Adapters[string(openrtb_ext.BidderSovrn)].Endpoint),
diff --git a/static/bidder-info/lifestreet.yaml b/static/bidder-info/e_volution.yaml
similarity index 56%
rename from static/bidder-info/lifestreet.yaml
rename to static/bidder-info/e_volution.yaml
index 34dc4eca..6ea9dc7b 100644
--- a/static/bidder-info/lifestreet.yaml
+++ b/static/bidder-info/e_volution.yaml
@@ -1,11 +1,14 @@
 maintainer:
-  email: "mobile.tech@lifestreet.com"
-gvlVendorID: 67
+  email: "admin@e-volution.ai"
+gvlVendorID: 957
 capabilities:
   app:
     mediaTypes:
       - banner
+      - video
+      - native
   site:
     mediaTypes:
       - banner
       - video
+      - native
\ No newline at end of file
diff --git a/static/bidder-params/criteo.json b/static/bidder-params/criteo.json
index 9d348a7e..88c6fba5 100644
--- a/static/bidder-params/criteo.json
+++ b/static/bidder-params/criteo.json
@@ -1,30 +1,50 @@
-{
-    "$schema": "http://json-schema.org/draft-04/schema#",
-    "title": "Criteo adapter params",
-    "description": "The schema to validate Criteo specific params accepted by Criteo adapter",
-    "type": "object",
-    "properties": {
-        "zoneid": {
-            "type": "number",
-            "description": "Impression's zone ID.",
-            "minimum": 0
-        },
-        "networkid": {
-            "type": "number",
-            "description": "Impression's network ID.",
-            "minimum": 0
-        }
-    },
-    "anyOf": [
-        {
-            "required": [
-                "zoneid"
-            ]
-        },
-        {
-            "required": [
-                "networkid"
-            ]
-        }
-    ]
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Criteo adapter params",
+    "description": "The schema to validate Criteo specific params accepted by Criteo adapter",
+    "type": "object",
+    "properties": {
+        "zoneid": {
+            "type": "integer",
+            "description": "Impression's zone ID.",
+            "minimum": 0
+        },
+        "zoneId": {
+            "type": "integer",
+            "description": "Impression's zone ID, preferred.",
+            "minimum": 0
+        },
+        "networkid": {
+            "type": "integer",
+            "description": "Impression's network ID.",
+            "minimum": 0
+        },
+        "networkId": {
+            "type": "integer",
+            "description": "Impression's network ID, preferred.",
+            "minimum": 0
+        }
+    },
+    "anyOf": [
+        {
+            "required": [
+                "zoneid"
+            ]
+        },
+        {
+            "required": [
+                "zoneId"
+            ]
+        },
+        {
+            "required": [
+                "networkid"
+            ]
+        },
+        {
+            "required": [
+                "networkId"
+            ]
+        }
+    ]
 }
\ No newline at end of file
diff --git a/static/bidder-params/e_volution.json b/static/bidder-params/e_volution.json
new file mode 100644
index 00000000..18de2a60
--- /dev/null
+++ b/static/bidder-params/e_volution.json
@@ -0,0 +1,13 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "E-volution Adapter Params",
+    "description": "A schema which validates params accepted by the E-volution adapter",
+    "type": "object",
+    "properties": {
+      "key": {
+        "type": "string",
+        "description": "network or placement key"
+      }
+    },
+    "required": ["key"]
+  }
\ No newline at end of file
diff --git a/static/bidder-params/lifestreet.json b/static/bidder-params/lifestreet.json
deleted file mode 100644
index 2190d761..00000000
--- a/static/bidder-params/lifestreet.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "$schema": "http://json-schema.org/draft-04/schema#",
-  "title": "Lifestreet Adapter Params",
-  "description": "A schema which validates params accepted by the Lifestreet adapter",
-  "type": "object",
-  "properties": {
-    "slot_tag": {
-      "type": "string",
-      "description": "A tag which identifies the ad slot"
-    }
-  },
-  "required": ["slot_tag"]
-}
diff --git a/usersync/usersyncers/syncer.go b/usersync/usersyncers/syncer.go
index 1c4e809e..88752f4d 100644
--- a/usersync/usersyncers/syncer.go
+++ b/usersync/usersyncers/syncer.go
@@ -39,6 +39,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/datablocks"
 	"github.com/prebid/prebid-server/adapters/deepintent"
 	"github.com/prebid/prebid-server/adapters/dmx"
+	"github.com/prebid/prebid-server/adapters/e_volution"
 	"github.com/prebid/prebid-server/adapters/emx_digital"
 	"github.com/prebid/prebid-server/adapters/engagebdr"
 	"github.com/prebid/prebid-server/adapters/eplanning"
@@ -51,7 +52,6 @@ import (
 	"github.com/prebid/prebid-server/adapters/ix"
 	"github.com/prebid/prebid-server/adapters/jixie"
 	"github.com/prebid/prebid-server/adapters/krushmedia"
-	"github.com/prebid/prebid-server/adapters/lifestreet"
 	"github.com/prebid/prebid-server/adapters/lockerdome"
 	"github.com/prebid/prebid-server/adapters/logicad"
 	"github.com/prebid/prebid-server/adapters/lunamedia"
@@ -137,6 +137,7 @@ func NewSyncerMap(cfg *config.Configuration) map[openrtb_ext.BidderName]usersync
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderDeepintent, deepintent.NewDeepintentSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderDmx, dmx.NewDmxSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderEmxDigital, emx_digital.NewEMXDigitalSyncer)
+	insertIntoMap(cfg, syncers, openrtb_ext.BidderEVolution, evolution.NewEvolutionSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderEngageBDR, engagebdr.NewEngageBDRSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderEPlanning, eplanning.NewEPlanningSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderAudienceNetwork, audienceNetwork.NewFacebookSyncer)
@@ -149,7 +150,6 @@ func NewSyncerMap(cfg *config.Configuration) map[openrtb_ext.BidderName]usersync
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderIx, ix.NewIxSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderJixie, jixie.NewJixieSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderKrushmedia, krushmedia.NewKrushmediaSyncer)
-	insertIntoMap(cfg, syncers, openrtb_ext.BidderLifestreet, lifestreet.NewLifestreetSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderLockerDome, lockerdome.NewLockerDomeSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderLogicad, logicad.NewLogicadSyncer)
 	insertIntoMap(cfg, syncers, openrtb_ext.BidderLunaMedia, lunamedia.NewLunaMediaSyncer)


Test patch:
diff --git a/adapters/criteo/criteotest/supplemental/multislots-alt-case.json b/adapters/criteo/criteotest/supplemental/multislots-alt-case.json
new file mode 100644
index 00000000..beb855e3
--- /dev/null
+++ b/adapters/criteo/criteotest/supplemental/multislots-alt-case.json
@@ -0,0 +1,232 @@
+{
+    "mockBidRequest": {
+      "id": "test-request-id",
+      "site": {
+        "id": "site-id",
+        "page": "criteo.com"
+      },
+      "device": {
+        "os": "android",
+        "ip": "91.199.242.236",
+        "ua": "random user agent"
+      },
+      "user": {
+        "ext": {
+          "eids": [{
+            "source": "criteo.com",
+            "uids": [{
+              "id": "criteo-eid"
+            }]
+          }]
+        }
+      },
+      "imp": [
+        {
+          "id": "test-imp-id-1",
+          "banner": {
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          },
+          "ext": {
+            "bidder": {
+              "zoneId": 123456,
+              "networkId": 78910
+            }
+          }
+        },
+        {
+          "id": "test-imp-id-2",
+          "banner": {
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          },
+          "ext": {
+            "bidder": {
+              "zoneId": 7891011,
+              "networkId": 78910
+            }
+          }
+        },
+        {
+          "id": "test-imp-id-3",
+          "banner": {
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          },
+          "ext": {
+            "bidder": {
+              "zoneId": 121314,
+              "networkId": 78910
+            }
+          }
+        }
+      ]
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "https://bidder.criteo.com/cdb?profileId=230",
+          "headers": {
+            "X-Forwarded-For": [
+              "91.199.242.236"
+            ],
+            "User-Agent": [
+              "random user agent"
+            ]
+          },
+          "body": {
+            "id": "test-request-id",
+            "publisher": {
+              "siteid": "site-id",
+              "url": "criteo.com",
+              "networkid": 78910
+            },
+            "user": {
+              "ip": "91.199.242.236",
+              "ua": "random user agent",
+              "deviceos": "android",
+              "deviceidtype": "gaid"
+            },
+            "gdprconsent": {},
+            "slots": [
+              {
+                "slotid": "00000000-0000-0000-00000000",
+                "impid": "test-imp-id-1",
+                "zoneid": 123456,
+                "networkid": 78910,
+                "sizes": [
+                  "300x250"
+                ]
+              },
+              {
+                "slotid": "00000000-0000-0000-00000000",
+                "impid": "test-imp-id-2",
+                "zoneid": 7891011,
+                "networkid": 78910,
+                "sizes": [
+                  "300x250"
+                ]
+              },
+              {
+                "slotid": "00000000-0000-0000-00000000",
+                "impid": "test-imp-id-3",
+                "zoneid": 121314,
+                "networkid": 78910,
+                "sizes": [
+                  "300x250"
+                ]
+              }
+            ],
+            "eids": [
+              {
+                "source": "criteo.com",
+                "uids": [
+                  {
+                    "id": "criteo-eid"
+                  }
+                ]
+              }
+            ]
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "slots": [
+              {
+                "id": "test-slot-id-1",
+                "impid": "test-imp-id-1",
+                "zoneid": 123456,
+                "networkid": 78910,
+                "cpm": 0.1,
+                "currency": "USD",
+                "width": 300,
+                "height": 250,
+                "creativeid": "creative-123",
+                "creative": "<iframe id='789abc' name='789abc' src='http://creative-url.criteo.com'></iframe>"
+              },
+              {
+                "id": "test-slot-id-2",
+                "impid": "test-imp-id-2",
+                "zoneid": 7891011,
+                "networkid": 78910,
+                "cpm": 0.2,
+                "currency": "USD",
+                "width": 320,
+                "height": 50,
+                "creativeid": "creative-123",
+                "creative": "<iframe id='789abc' name='789abc' src='http://creative-url.criteo.com'></iframe>"
+              },
+              {
+                "id": "test-slot-id-3",
+                "impid": "test-imp-id-3",
+                "zoneid": 121314,
+                "networkid": 78910,
+                "cpm": 0.3,
+                "currency": "USD",
+                "width": 300,
+                "height": 600,
+                "creativeid": "creative-123",
+                "creative": "<iframe id='789abc' name='789abc' src='http://creative-url.criteo.com'></iframe>"
+              }
+            ]
+          }
+        }
+      }
+    ],
+    "expectedBidResponses": [
+      {
+        "currency": "USD",
+        "bids": [
+          {
+            "bid": {
+              "id": "test-slot-id-1",
+              "impid": "test-imp-id-1",
+              "price": 0.1,
+              "crid": "creative-123",
+              "adm": "<iframe id='789abc' name='789abc' src='http://creative-url.criteo.com'></iframe>",
+              "w": 300,
+              "h": 250
+            },
+            "type": "banner"
+          },
+          {
+            "bid": {
+              "id": "test-slot-id-2",
+              "impid": "test-imp-id-2",
+              "price": 0.2,
+              "crid": "creative-123",
+              "adm": "<iframe id='789abc' name='789abc' src='http://creative-url.criteo.com'></iframe>",
+              "w": 320,
+              "h": 50
+            },
+            "type": "banner"
+          },
+          {
+            "bid": {
+              "id": "test-slot-id-3",
+              "impid": "test-imp-id-3",
+              "price": 0.3,
+              "crid": "creative-123",
+              "adm": "<iframe id='789abc' name='789abc' src='http://creative-url.criteo.com'></iframe>",
+              "w": 300,
+              "h": 600
+            },
+            "type": "banner"
+          }
+        ]
+      }
+    ]
+  }
diff --git a/adapters/criteo/params_test.go b/adapters/criteo/params_test.go
index 73ace617..9c836769 100644
--- a/adapters/criteo/params_test.go
+++ b/adapters/criteo/params_test.go
@@ -41,9 +41,13 @@ func TestInvalidParams(t *testing.T) {
 
 var validParams = []string{
 	`{"zoneid": 123456}`,
+	`{"zoneId": 123456}`,
 	`{"networkid": 78910}`,
+	`{"networkId": 78910}`,
 	`{"zoneid": 123456, "networkid": 78910}`,
+	`{"zoneId": 123456, "networkId": 78910}`,
 	`{"zoneid": 0, "networkid": 0}`,
+	`{"zoneId": 0, "networkId": 0}`,
 }
 
 var invalidParams = []string{
@@ -55,8 +59,11 @@ var invalidParams = []string{
 	`[]`,
 	`{}`,
 	`{"zoneid": -123}`,
+	`{"zoneId": -123}`,
 	`{"networkid": -321}`,
+	`{"networkId": -321}`,
 	`{"zoneid": -123, "networkid": -321}`,
+	`{"zoneId": -123, "networkId": -321}`,
 	`{"zoneid": -1}`,
 	`{"networkid": -1}`,
 	`{"zoneid": -1, "networkid": -1}`,
diff --git a/adapters/e_volution/evolution_test.go b/adapters/e_volution/evolution_test.go
new file mode 100644
index 00000000..1d2ee7ef
--- /dev/null
+++ b/adapters/e_volution/evolution_test.go
@@ -0,0 +1,18 @@
+package evolution
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/adapters/adapterstest"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/openrtb_ext"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderEVolution, config.Adapter{
+		Endpoint: "http://service.e-volution.ai/pbserver"})
+
+	assert.NoError(t, buildErr)
+	adapterstest.RunJSONBidderTest(t, "evolutiontest", bidder)
+}
diff --git a/adapters/e_volution/evolutiontest/exemplary/banner-without-mediatype.json b/adapters/e_volution/evolutiontest/exemplary/banner-without-mediatype.json
new file mode 100644
index 00000000..251fe8c6
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/exemplary/banner-without-mediatype.json
@@ -0,0 +1,168 @@
+{
+  "mockBidRequest": {
+    "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+    "imp": [{
+      "id": "126365",
+      "secure": 1,
+      "bidfloor": 0.20,
+      "bidfloorcur": "USD",
+      "banner": {
+        "w": 300,
+        "h": 250,
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      },
+      "ext": {
+        "bidder": {
+          "key": "test_banner"
+        }
+      }
+    }],
+    "device": {
+      "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+      "geo": {
+        "country": "MEX",
+        "region": "CMX",
+        "city": "Mexico City",
+        "lat": 19.42,
+        "lon": -99.1663
+      },
+      "ip": "189.146.118.247",
+      "devicetype": 4,
+      "language": "it"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+      "ext": {
+        "consent": ""
+      }
+    },
+    "site": {
+      "id": "12",
+      "domain": "milano.repubblica.it",
+      "cat": ["IAB12"],
+      "page": "https://milano.repubblica.it",
+      "publisher": {
+        "id": "45672"
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "imp": [{
+            "id": "126365",
+            "banner": {
+              "format": [{
+                "w": 300,
+                "h": 250
+              }],
+              "w": 300,
+              "h": 250
+            },
+            "bidfloor": 0.2,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "ext": {
+              "bidder": {
+                "key": "test_banner"
+              }
+            }
+          }],
+          "site": {
+            "id": "12",
+            "domain": "milano.repubblica.it",
+            "cat": ["IAB12"],
+            "page": "https://milano.repubblica.it",
+            "publisher": {
+              "id": "45672"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+            "geo": {
+              "lat": 19.42,
+              "lon": -99.1663,
+              "country": "MEX",
+              "region": "CMX",
+              "city": "Mexico City"
+            },
+            "ip": "189.146.118.247",
+            "devicetype": 4,
+            "language": "it"
+          },
+          "user": {
+            "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+            "ext": {
+              "consent": ""
+            }
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "bidid": "880184da7ec02b1f42802acb46b63b3c",
+          "seatbid": [{
+            "bid": [{
+              "id": "6ca51ef38eb42820d27503ee96b634b5",
+              "impid": "126365",
+              "price": 0.1,
+              "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+              "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+              "adm": "<iframe srcdoc=\"<p style='text-align: center'>Test Mode</p>\" width=\"300\" height=\"250\" scrolling=\"no\" style=\"background-color:lightgray;border:0;overflow:hidden\"></iframe><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=880184da7ec02b1f42802acb46b63b3c&cp=${AUCTION_PRICE}\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute; opacity: 0;\"><iframe  src=\"https://sync.e-volution.ai/html?gdpr=0&gdpr_consent=&ccpa=\" width=\"0\" height=\"0\" style=\"display: none;\"></iframe><img src=\"https://adrta.com/i?clid=vrl&paid=bidlab&avid=&caid=&plid=&publisherId=repubblica.it&siteId=12&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fmilano.repubblica.it&kv3=&kv4=189.146.118.247&kv5=1622069609078513&kv7=-1&kv9=&kv11=&kv12=&kv15=MEX&kv16=19.42&kv17=-99.1663&kv18=&kv19=&kv23=&kv24=&kv25=&kv26=&kv27=Mozilla%2F5.0%20(iPhone%3B%20CPU%20iPhone%20OS%2014_5_1%20like%20Mac%20OS%20X)%20AppleWebKit%2F605.1.15%20(KHTML%2C%20like%20Gecko)%20Version%2F14.1%20Mobile%2F15E148%20Safari%2F604.1&kv28=&cb=1622069609078513&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script>",
+              "adomain": ["test.com"],
+              "cat": ["IAB24"],
+              "cid": "1IP31",
+              "crid": "1KS13",
+              "w": 0,
+              "h": 0
+            }],
+            "seat": "1"
+          }],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "6ca51ef38eb42820d27503ee96b634b5",
+            "impid": "126365",
+            "price": 0.1,
+            "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+            "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+            "adm": "<iframe srcdoc=\"<p style='text-align: center'>Test Mode</p>\" width=\"300\" height=\"250\" scrolling=\"no\" style=\"background-color:lightgray;border:0;overflow:hidden\"></iframe><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=880184da7ec02b1f42802acb46b63b3c&cp=${AUCTION_PRICE}\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute; opacity: 0;\"><iframe  src=\"https://sync.e-volution.ai/html?gdpr=0&gdpr_consent=&ccpa=\" width=\"0\" height=\"0\" style=\"display: none;\"></iframe><img src=\"https://adrta.com/i?clid=vrl&paid=bidlab&avid=&caid=&plid=&publisherId=repubblica.it&siteId=12&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fmilano.repubblica.it&kv3=&kv4=189.146.118.247&kv5=1622069609078513&kv7=-1&kv9=&kv11=&kv12=&kv15=MEX&kv16=19.42&kv17=-99.1663&kv18=&kv19=&kv23=&kv24=&kv25=&kv26=&kv27=Mozilla%2F5.0%20(iPhone%3B%20CPU%20iPhone%20OS%2014_5_1%20like%20Mac%20OS%20X)%20AppleWebKit%2F605.1.15%20(KHTML%2C%20like%20Gecko)%20Version%2F14.1%20Mobile%2F15E148%20Safari%2F604.1&kv28=&cb=1622069609078513&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script>",
+            "adomain": ["test.com"],
+            "cat": ["IAB24"],
+            "cid": "1IP31",
+            "crid": "1KS13"
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/exemplary/banner.json b/adapters/e_volution/evolutiontest/exemplary/banner.json
new file mode 100644
index 00000000..68fda490
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/exemplary/banner.json
@@ -0,0 +1,174 @@
+{
+  "mockBidRequest": {
+    "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+    "imp": [{
+      "id": "126365",
+      "secure": 1,
+      "bidfloor": 0.20,
+      "bidfloorcur": "USD",
+      "banner": {
+        "w": 300,
+        "h": 250,
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      },
+      "ext": {
+        "bidder": {
+          "key": "test_banner"
+        }
+      }
+    }],
+    "device": {
+      "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+      "geo": {
+        "country": "MEX",
+        "region": "CMX",
+        "city": "Mexico City",
+        "lat": 19.42,
+        "lon": -99.1663
+      },
+      "ip": "189.146.118.247",
+      "devicetype": 4,
+      "language": "it"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+      "ext": {
+        "consent": ""
+      }
+    },
+    "site": {
+      "id": "12",
+      "domain": "milano.repubblica.it",
+      "cat": ["IAB12"],
+      "page": "https://milano.repubblica.it",
+      "publisher": {
+        "id": "45672"
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "imp": [{
+            "id": "126365",
+            "banner": {
+              "format": [{
+                "w": 300,
+                "h": 250
+              }],
+              "w": 300,
+              "h": 250
+            },
+            "bidfloor": 0.2,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "ext": {
+              "bidder": {
+                "key": "test_banner"
+              }
+            }
+          }],
+          "site": {
+            "id": "12",
+            "domain": "milano.repubblica.it",
+            "cat": ["IAB12"],
+            "page": "https://milano.repubblica.it",
+            "publisher": {
+              "id": "45672"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+            "geo": {
+              "lat": 19.42,
+              "lon": -99.1663,
+              "country": "MEX",
+              "region": "CMX",
+              "city": "Mexico City"
+            },
+            "ip": "189.146.118.247",
+            "devicetype": 4,
+            "language": "it"
+          },
+          "user": {
+            "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+            "ext": {
+              "consent": ""
+            }
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "bidid": "880184da7ec02b1f42802acb46b63b3c",
+          "seatbid": [{
+            "bid": [{
+              "id": "6ca51ef38eb42820d27503ee96b634b5",
+              "impid": "126365",
+              "price": 0.1,
+              "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+              "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+              "adm": "<iframe srcdoc=\"<p style='text-align: center'>Test Mode</p>\" width=\"300\" height=\"250\" scrolling=\"no\" style=\"background-color:lightgray;border:0;overflow:hidden\"></iframe><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=880184da7ec02b1f42802acb46b63b3c&cp=${AUCTION_PRICE}\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute; opacity: 0;\"><iframe  src=\"https://sync.e-volution.ai/html?gdpr=0&gdpr_consent=&ccpa=\" width=\"0\" height=\"0\" style=\"display: none;\"></iframe><img src=\"https://adrta.com/i?clid=vrl&paid=bidlab&avid=&caid=&plid=&publisherId=repubblica.it&siteId=12&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fmilano.repubblica.it&kv3=&kv4=189.146.118.247&kv5=1622069609078513&kv7=-1&kv9=&kv11=&kv12=&kv15=MEX&kv16=19.42&kv17=-99.1663&kv18=&kv19=&kv23=&kv24=&kv25=&kv26=&kv27=Mozilla%2F5.0%20(iPhone%3B%20CPU%20iPhone%20OS%2014_5_1%20like%20Mac%20OS%20X)%20AppleWebKit%2F605.1.15%20(KHTML%2C%20like%20Gecko)%20Version%2F14.1%20Mobile%2F15E148%20Safari%2F604.1&kv28=&cb=1622069609078513&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script>",
+              "adomain": ["test.com"],
+              "cat": ["IAB24"],
+              "cid": "1IP31",
+              "crid": "1KS13",
+              "w": 0,
+              "h": 0,
+              "ext": {
+                "mediaType": "banner"
+              }
+            }],
+            "seat": "1"
+          }],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "6ca51ef38eb42820d27503ee96b634b5",
+            "impid": "126365",
+            "price": 0.1,
+            "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+            "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=880184da7ec02b1f42802acb46b63b3c&price=${AUCTION_PRICE}",
+            "adm": "<iframe srcdoc=\"<p style='text-align: center'>Test Mode</p>\" width=\"300\" height=\"250\" scrolling=\"no\" style=\"background-color:lightgray;border:0;overflow:hidden\"></iframe><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=880184da7ec02b1f42802acb46b63b3c&cp=${AUCTION_PRICE}\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><img src=\"https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute; opacity: 0;\"><iframe  src=\"https://sync.e-volution.ai/html?gdpr=0&gdpr_consent=&ccpa=\" width=\"0\" height=\"0\" style=\"display: none;\"></iframe><img src=\"https://adrta.com/i?clid=vrl&paid=bidlab&avid=&caid=&plid=&publisherId=repubblica.it&siteId=12&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fmilano.repubblica.it&kv3=&kv4=189.146.118.247&kv5=1622069609078513&kv7=-1&kv9=&kv11=&kv12=&kv15=MEX&kv16=19.42&kv17=-99.1663&kv18=&kv19=&kv23=&kv24=&kv25=&kv26=&kv27=Mozilla%2F5.0%20(iPhone%3B%20CPU%20iPhone%20OS%2014_5_1%20like%20Mac%20OS%20X)%20AppleWebKit%2F605.1.15%20(KHTML%2C%20like%20Gecko)%20Version%2F14.1%20Mobile%2F15E148%20Safari%2F604.1&kv28=&cb=1622069609078513&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]\" width=\"1\" height=\"1\" alt=\"\" style=\"position: absolute\"><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script><script src=\"https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=milano.repubblica.it&ui=460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5&ap=&sr=-1&pp=repubblica.it&ti=d910ceef496ff2d746176506e296f4b3_z53356_a126365&md=1&de=4&si=12&dm=300x250&gt=MX&ac=&pc=&cr=&pv=684e0715-f9e8-42c9-a804-e011c38ae8a1&c1=1&c2=-1&cb=16220696090799003\" async=\"true\"></script>",
+            "adomain": ["test.com"],
+            "cat": ["IAB24"],
+            "cid": "1IP31",
+            "crid": "1KS13",
+            "ext": {
+              "mediaType": "banner"
+            }
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/exemplary/native.json b/adapters/e_volution/evolutiontest/exemplary/native.json
new file mode 100644
index 00000000..724f55f6
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/exemplary/native.json
@@ -0,0 +1,181 @@
+{
+  "mockBidRequest": {
+    "id": "a1580f2f-be6d-11eb-a150-d094662c1c35",
+    "tmax": 500,
+    "at": 1,
+    "device": {
+      "dnt": 0,
+      "devicetype": 2,
+      "js": 1,
+      "ip": "79.26.58.249",
+      "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
+      "os": "Mac OS",
+      "language": "en",
+      "geo": {
+        "country": "ITA"
+      }
+    },
+    "user": {
+      "id": "l1eHS1lZE41a",
+      "ext": {
+        "consent": "CPCfkEbPCfkEbERACAENBbCsAP_AAH_AAAAAHetf_X_fb39j-_59_9t0eY1f9_7_v-wzjhfds-8NyPvX_L8X42M7PF36pq4KuR4Eu3LBIQFlHOHUTUmw6okVrTPsak2Mr7NKJ7LEinMbe2dYGHtfn91TuZKYr_7s_9fz__-v_v__79f3r-3_3_vp9X---_e_V399xKB3QBJhqXwAWYljgSTRpVCiBCFYSHQCgAooBhaJrCAhYFOyuAj1BAwAQGoCMCIEGIKMWAQAAAQBIREBIAeCARAEQCAAEAKkBCAAiYBBYAWBgEAAoBoWIEUAQgSEGRwVHKYEBEi0UE8lYAlF3sYYQhlFgBQKP6KjARKEAAAA.YAAAAAAAAAAA"
+      }
+    },
+    "site": {
+      "id": "57078628",
+      "domain": "www.affaritaliani.it",
+      "page": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html",
+      "ref": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html?refresh_ce",
+      "name": "www.affaritaliani.it",
+      "publisher": {
+        "id": "439696",
+        "name": "www.affaritaliani.it"
+      },
+      "cat": [
+        "IAB12"
+      ]
+    },
+    "publisher": {},
+    "cur": [
+      "USD"
+    ],
+    "bcat": [
+      "IAB12-2",
+      "IAB9-7"
+    ],
+    "imp": [{
+      "id": "1",
+      "bidfloor": 0.1,
+      "bidfloorcur": "USD",
+      "instl": 0,
+      "secure": 1,
+      "native": {
+        "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}",
+        "ver": "1.1"
+      },
+      "ext": {
+        "bidder": {
+          "key": "test_native"
+        }
+      }
+    }],
+    "regs": {
+      "ext": {
+        "gdpr": 1
+      }
+    }
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://service.e-volution.ai/pbserver",
+      "body": {
+        "id": "a1580f2f-be6d-11eb-a150-d094662c1c35",
+        "imp": [{
+          "id": "1",
+          "native": {
+            "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}",
+            "ver": "1.1"
+          },
+          "bidfloor": 0.1,
+          "bidfloorcur": "USD",
+          "secure": 1,
+          "ext": {
+            "bidder": {
+              "key": "test_native"
+            }
+          }
+        }],
+        "site": {
+          "id": "57078628",
+          "name": "www.affaritaliani.it",
+          "domain": "www.affaritaliani.it",
+          "cat": ["IAB12"],
+          "page": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html",
+          "ref": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html?refresh_ce",
+          "publisher": {
+            "id": "439696",
+            "name": "www.affaritaliani.it"
+          }
+        },
+        "device": {
+          "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
+          "geo": {
+            "country": "ITA"
+          },
+          "dnt": 0,
+          "ip": "79.26.58.249",
+          "devicetype": 2,
+          "os": "Mac OS",
+          "js": 1,
+          "language": "en"
+        },
+        "user": {
+          "id": "l1eHS1lZE41a",
+          "ext": {
+            "consent": "CPCfkEbPCfkEbERACAENBbCsAP_AAH_AAAAAHetf_X_fb39j-_59_9t0eY1f9_7_v-wzjhfds-8NyPvX_L8X42M7PF36pq4KuR4Eu3LBIQFlHOHUTUmw6okVrTPsak2Mr7NKJ7LEinMbe2dYGHtfn91TuZKYr_7s_9fz__-v_v__79f3r-3_3_vp9X---_e_V399xKB3QBJhqXwAWYljgSTRpVCiBCFYSHQCgAooBhaJrCAhYFOyuAj1BAwAQGoCMCIEGIKMWAQAAAQBIREBIAeCARAEQCAAEAKkBCAAiYBBYAWBgEAAoBoWIEUAQgSEGRwVHKYEBEi0UE8lYAlF3sYYQhlFgBQKP6KjARKEAAAA.YAAAAAAAAAAA"
+          }
+        },
+        "at": 1,
+        "tmax": 500,
+        "cur": ["USD"],
+        "bcat": ["IAB12-2", "IAB9-7"],
+        "regs": {
+          "ext": {
+            "gdpr": 1
+          }
+        }
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": {
+        "id": "a1580f2f-be6d-11eb-a150-d094662c1c35",
+        "bidid": "359da97d0384d8a14767029c18fd840d",
+        "seatbid": [{
+          "bid": [{
+            "id": "1af875cae46410c18e4d8b1fcc909e6c",
+            "impid": "1",
+            "price": 0.1,
+            "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=359da97d0384d8a14767029c18fd840d&price=${AUCTION_PRICE}",
+            "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=359da97d0384d8a14767029c18fd840d&price=${AUCTION_PRICE}",
+            "adm": "{\"link\":{\"url\":\"https://e-volution.ai\"},\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"text\":\"Viralize test\"}},{\"id\":2,\"required\":1,\"img\":{}},{\"id\":4,\"data\":{\"value\":\"3$\"}},{\"id\":5,\"data\":{\"value\":\"2$\"}},{\"id\":6,\"data\":{\"value\":\"viralize\"}}],\"ver\":\"1.1\",\"imptrackers\":[\"https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=359da97d0384d8a14767029c18fd840d&cp=${AUCTION_PRICE}\",\"https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=1&gdpr_consent=CPCfkEbPCfkEbERACAENBbCsAP_AAH_AAAAAHetf_X_fb39j-_59_9t0eY1f9_7_v-wzjhfds-8NyPvX_L8X42M7PF36pq4KuR4Eu3LBIQFlHOHUTUmw6okVrTPsak2Mr7NKJ7LEinMbe2dYGHtfn91TuZKYr_7s_9fz__-v_v__79f3r-3_3_vp9X---_e_V399xKB3QBJhqXwAWYljgSTRpVCiBCFYSHQCgAooBhaJrCAhYFOyuAj1BAwAQGoCMCIEGIKMWAQAAAQBIREBIAeCARAEQCAAEAKkBCAAiYBBYAWBgEAAoBoWIEUAQgSEGRwVHKYEBEi0UE8lYAlF3sYYQhlFgBQKP6KjARKEAAAA.YAAAAAAAAAAA&ccpa_consent=\"]}",
+            "adomain": ["test.com"],
+            "cat": ["IAB24"],
+            "cid": "1IP31",
+            "crid": "1KS13",
+            "w": 0,
+            "h": 0,
+            "ext": {
+              "mediaType": "native"
+            }
+          }],
+          "seat": "1"
+        }],
+        "cur": "USD"
+      }
+    }
+  }],
+
+  "expectedBidResponses": [{
+    "currency": "USD",
+    "bids": [{
+      "bid": {
+        "id": "1af875cae46410c18e4d8b1fcc909e6c",
+        "impid": "1",
+        "price": 0.1,
+        "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=359da97d0384d8a14767029c18fd840d&price=${AUCTION_PRICE}",
+        "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=359da97d0384d8a14767029c18fd840d&price=${AUCTION_PRICE}",
+        "adm": "{\"link\":{\"url\":\"https://e-volution.ai\"},\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"text\":\"Viralize test\"}},{\"id\":2,\"required\":1,\"img\":{}},{\"id\":4,\"data\":{\"value\":\"3$\"}},{\"id\":5,\"data\":{\"value\":\"2$\"}},{\"id\":6,\"data\":{\"value\":\"viralize\"}}],\"ver\":\"1.1\",\"imptrackers\":[\"https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=359da97d0384d8a14767029c18fd840d&cp=${AUCTION_PRICE}\",\"https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=1&gdpr_consent=CPCfkEbPCfkEbERACAENBbCsAP_AAH_AAAAAHetf_X_fb39j-_59_9t0eY1f9_7_v-wzjhfds-8NyPvX_L8X42M7PF36pq4KuR4Eu3LBIQFlHOHUTUmw6okVrTPsak2Mr7NKJ7LEinMbe2dYGHtfn91TuZKYr_7s_9fz__-v_v__79f3r-3_3_vp9X---_e_V399xKB3QBJhqXwAWYljgSTRpVCiBCFYSHQCgAooBhaJrCAhYFOyuAj1BAwAQGoCMCIEGIKMWAQAAAQBIREBIAeCARAEQCAAEAKkBCAAiYBBYAWBgEAAoBoWIEUAQgSEGRwVHKYEBEi0UE8lYAlF3sYYQhlFgBQKP6KjARKEAAAA.YAAAAAAAAAAA&ccpa_consent=\"]}",
+        "adomain": ["test.com"],
+        "cat": ["IAB24"],
+        "cid": "1IP31",
+        "crid": "1KS13",
+        "ext": {
+          "mediaType": "native"
+        }
+      },
+      "type": "native"
+    }]
+  }]
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/exemplary/video.json b/adapters/e_volution/evolutiontest/exemplary/video.json
new file mode 100644
index 00000000..f7a03146
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/exemplary/video.json
@@ -0,0 +1,200 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [{
+      "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+      "video": {
+        "mimes": ["video/mp4", "video/ogg", "video/webm"],
+        "minduration": 3,
+        "maxduration": 3000,
+        "protocols": [2, 3, 5, 6, 7, 8],
+        "w": 480,
+        "h": 320,
+        "linearity": 1,
+        "playbackmethod": [2],
+        "pos": 0
+      },
+      "bidfloor": 0.40404,
+      "bidfloorcur": "USD",
+      "secure": 1,
+      "exp": 3600,
+      "ext": {
+        "bidder": {
+          "key": "test_video"
+        }
+      }
+    }],
+    "site": {
+      "id": "1c94d85ea1a55ebf3325a82935240614",
+      "domain": "kiwilimon.com",
+      "cat": ["IAB1", "IAB2", "IAB3", "IAB4", "IAB5", "IAB6", "IAB7", "IAB8", "IAB9", "IAB10", "IAB11", "IAB13", "IAB14", "IAB15", "IAB17", "IAB18"],
+      "page": "https://kiwilimon.com/",
+      "publisher": {
+        "id": "866d6b3a4a483ed4a454a1acaa588852"
+      },
+      "ext": {
+        "amp": 0
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": ["USD"],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [{
+            "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+            "video": {
+              "mimes": ["video/mp4", "video/ogg", "video/webm"],
+              "minduration": 3,
+              "maxduration": 3000,
+              "protocols": [2, 3, 5, 6, 7, 8],
+              "w": 480,
+              "h": 320,
+              "linearity": 1,
+              "playbackmethod": [2],
+              "pos": 0
+            },
+            "bidfloor": 0.40404,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "exp": 3600,
+            "ext": {
+              "bidder": {
+                "key": "test_video"
+              }
+            }
+          }],
+          "site": {
+            "id": "1c94d85ea1a55ebf3325a82935240614",
+            "domain": "kiwilimon.com",
+            "cat": ["IAB1", "IAB2", "IAB3", "IAB4", "IAB5", "IAB6", "IAB7", "IAB8", "IAB9", "IAB10", "IAB11", "IAB13", "IAB14", "IAB15", "IAB17", "IAB18"],
+            "page": "https://kiwilimon.com/",
+            "publisher": {
+              "id": "866d6b3a4a483ed4a454a1acaa588852"
+            },
+            "ext": {
+              "amp": 0
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": ["USD"],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "bidid": "ccbd63285c0e7b69602d90319bda6be4",
+          "seatbid": [{
+            "bid": [{
+              "id": "7f6c6d6ba432059a5305815a8d740283",
+              "impid": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "price": 0.1,
+              "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+              "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+              "adm": "<VAST version=\"2.0\"><Ad id=\"20001\" sequence=\"1\" conditionalAd=\"false\"><InLine><AdSystem version=\"4.0\"><![CDATA[iabtechlab]]></AdSystem><AdTitle><![CDATA[Inline Simple Ad]]></AdTitle><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://adrta.com/i?clid=vrl&paid=bidlab&dvid=v&avid=&caid=&plid=&publisherId=866d6b3a4a483ed4a454a1acaa588852&siteId=1c94d85ea1a55ebf3325a82935240614&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fkiwilimon.com%2F&kv3=&kv4=187.152.119.145&kv5=1622068800924671&kv7=-1&kv9=00%3A00%3A16&kv11=&kv12=&kv15=MEX&kv16=20.6668&kv17=-103.3918&kv18=&kv19=&kv23=Telmex&kv24=&kv25=&kv26=windows&kv27=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F88.0.4324.190%20Safari%2F537.36&kv28=&cb=1622068800924671&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=ccbd63285c0e7b69602d90319bda6be4&cp=${AUCTION_PRICE}]]></Impression><Creatives><Creative id=\"5480\" sequence=\"1\" adId=\"2447226\"><UniversalAdId idRegistry=\"Ad-ID\" idValue=\"8465\">8465</UniversalAdId><Linear><TrackingEvents></TrackingEvents><Duration>00:00:16</Duration><MediaFiles><MediaFile id=\"5241\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"2000\" width=\"1280\" height=\"720\" minBitrate=\"1500\" maxBitrate=\"2500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro.mp4]]></MediaFile><MediaFile id=\"5244\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"1000\" width=\"854\" height=\"480\" minBitrate=\"700\" maxBitrate=\"1500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-mid-resolution.mp4]]></MediaFile><MediaFile id=\"5246\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"600\" width=\"640\" height=\"360\" minBitrate=\"500\" maxBitrate=\"700\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-low-resolution.mp4]]></MediaFile></MediaFiles><VideoClicks><ClickThrough id=\"blog\"><![CDATA[https://iabtechlab.com]]></ClickThrough></VideoClicks></Linear></Creative></Creatives><Error><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}&ecode=[ERRORCODE]]]></Error></InLine></Ad></VAST>",
+              "adomain": ["test.com"],
+              "cat": ["IAB24"],
+              "cid": "1IP31",
+              "crid": "1KS13",
+              "w": 0,
+              "h": 0,
+              "ext": {
+                "mediaType": "video"
+              }
+            }],
+            "seat": "1"
+          }],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "7f6c6d6ba432059a5305815a8d740283",
+            "impid": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+            "price": 0.1,
+            "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+            "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+            "adm": "<VAST version=\"2.0\"><Ad id=\"20001\" sequence=\"1\" conditionalAd=\"false\"><InLine><AdSystem version=\"4.0\"><![CDATA[iabtechlab]]></AdSystem><AdTitle><![CDATA[Inline Simple Ad]]></AdTitle><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://adrta.com/i?clid=vrl&paid=bidlab&dvid=v&avid=&caid=&plid=&publisherId=866d6b3a4a483ed4a454a1acaa588852&siteId=1c94d85ea1a55ebf3325a82935240614&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fkiwilimon.com%2F&kv3=&kv4=187.152.119.145&kv5=1622068800924671&kv7=-1&kv9=00%3A00%3A16&kv11=&kv12=&kv15=MEX&kv16=20.6668&kv17=-103.3918&kv18=&kv19=&kv23=Telmex&kv24=&kv25=&kv26=windows&kv27=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F88.0.4324.190%20Safari%2F537.36&kv28=&cb=1622068800924671&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=ccbd63285c0e7b69602d90319bda6be4&cp=${AUCTION_PRICE}]]></Impression><Creatives><Creative id=\"5480\" sequence=\"1\" adId=\"2447226\"><UniversalAdId idRegistry=\"Ad-ID\" idValue=\"8465\">8465</UniversalAdId><Linear><TrackingEvents></TrackingEvents><Duration>00:00:16</Duration><MediaFiles><MediaFile id=\"5241\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"2000\" width=\"1280\" height=\"720\" minBitrate=\"1500\" maxBitrate=\"2500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro.mp4]]></MediaFile><MediaFile id=\"5244\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"1000\" width=\"854\" height=\"480\" minBitrate=\"700\" maxBitrate=\"1500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-mid-resolution.mp4]]></MediaFile><MediaFile id=\"5246\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"600\" width=\"640\" height=\"360\" minBitrate=\"500\" maxBitrate=\"700\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-low-resolution.mp4]]></MediaFile></MediaFiles><VideoClicks><ClickThrough id=\"blog\"><![CDATA[https://iabtechlab.com]]></ClickThrough></VideoClicks></Linear></Creative></Creatives><Error><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}&ecode=[ERRORCODE]]]></Error></InLine></Ad></VAST>",
+            "adomain": ["test.com"],
+            "cat": ["IAB24"],
+            "cid": "1IP31",
+            "crid": "1KS13",
+            "ext": {
+              "mediaType": "video"
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/params/race/banner.json b/adapters/e_volution/evolutiontest/params/race/banner.json
new file mode 100644
index 00000000..0a04c95b
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/params/race/banner.json
@@ -0,0 +1,3 @@
+{
+  "key": "test_banner"
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/params/race/native.json b/adapters/e_volution/evolutiontest/params/race/native.json
new file mode 100644
index 00000000..032b9dd5
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/params/race/native.json
@@ -0,0 +1,3 @@
+{
+  "key": "test_native"
+}
diff --git a/adapters/e_volution/evolutiontest/params/race/video.json b/adapters/e_volution/evolutiontest/params/race/video.json
new file mode 100644
index 00000000..87071003
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/params/race/video.json
@@ -0,0 +1,3 @@
+{
+  "key": "test_video"
+}
diff --git a/adapters/e_volution/evolutiontest/supplemental/bad-response.json b/adapters/e_volution/evolutiontest/supplemental/bad-response.json
new file mode 100644
index 00000000..75f3cb45
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/supplemental/bad-response.json
@@ -0,0 +1,158 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [{
+      "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+      "video": {
+        "mimes": ["video/mp4", "video/ogg", "video/webm"],
+        "minduration": 3,
+        "maxduration": 3000,
+        "protocols": [2, 3, 5, 6, 7, 8],
+        "w": 480,
+        "h": 320,
+        "linearity": 1,
+        "playbackmethod": [2],
+        "pos": 0
+      },
+      "bidfloor": 0.40404,
+      "bidfloorcur": "USD",
+      "secure": 1,
+      "exp": 3600,
+      "ext": {
+        "bidder": {
+          "key": "test_video"
+        }
+      }
+    }],
+    "site": {
+      "id": "1c94d85ea1a55ebf3325a82935240614",
+      "domain": "kiwilimon.com",
+      "cat": ["IAB1", "IAB2", "IAB3", "IAB4", "IAB5", "IAB6", "IAB7", "IAB8", "IAB9", "IAB10", "IAB11", "IAB13", "IAB14", "IAB15", "IAB17", "IAB18"],
+      "page": "https://kiwilimon.com/",
+      "publisher": {
+        "id": "866d6b3a4a483ed4a454a1acaa588852"
+      },
+      "ext": {
+        "amp": 0
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": ["USD"],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [{
+            "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+            "video": {
+              "mimes": ["video/mp4", "video/ogg", "video/webm"],
+              "minduration": 3,
+              "maxduration": 3000,
+              "protocols": [2, 3, 5, 6, 7, 8],
+              "w": 480,
+              "h": 320,
+              "linearity": 1,
+              "playbackmethod": [2],
+              "pos": 0
+            },
+            "bidfloor": 0.40404,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "exp": 3600,
+            "ext": {
+              "bidder": {
+                "key": "test_video"
+              }
+            }
+          }],
+          "site": {
+            "id": "1c94d85ea1a55ebf3325a82935240614",
+            "domain": "kiwilimon.com",
+            "cat": ["IAB1", "IAB2", "IAB3", "IAB4", "IAB5", "IAB6", "IAB7", "IAB8", "IAB9", "IAB10", "IAB11", "IAB13", "IAB14", "IAB15", "IAB17", "IAB18"],
+            "page": "https://kiwilimon.com/",
+            "publisher": {
+              "id": "866d6b3a4a483ed4a454a1acaa588852"
+            },
+            "ext": {
+              "amp": 0
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": ["USD"],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": ""
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad response, json: cannot unmarshal string into Go value of type openrtb2.BidResponse",
+      "comparison": "literal"
+    }
+  ],
+
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/supplemental/empty-seatbid.json b/adapters/e_volution/evolutiontest/supplemental/empty-seatbid.json
new file mode 100644
index 00000000..c9a103ae
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/supplemental/empty-seatbid.json
@@ -0,0 +1,149 @@
+{
+  "mockBidRequest": {
+    "id": "a1580f2f-be6d-11eb-a150-d094662c1c35",
+    "tmax": 500,
+    "at": 1,
+    "device": {
+      "dnt": 0,
+      "devicetype": 2,
+      "js": 1,
+      "ip": "79.26.58.249",
+      "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
+      "os": "Mac OS",
+      "language": "en",
+      "geo": {
+        "country": "ITA"
+      }
+    },
+    "user": {
+      "id": "l1eHS1lZE41a",
+      "ext": {
+        "consent": "CPCfkEbPCfkEbERACAENBbCsAP_AAH_AAAAAHetf_X_fb39j-_59_9t0eY1f9_7_v-wzjhfds-8NyPvX_L8X42M7PF36pq4KuR4Eu3LBIQFlHOHUTUmw6okVrTPsak2Mr7NKJ7LEinMbe2dYGHtfn91TuZKYr_7s_9fz__-v_v__79f3r-3_3_vp9X---_e_V399xKB3QBJhqXwAWYljgSTRpVCiBCFYSHQCgAooBhaJrCAhYFOyuAj1BAwAQGoCMCIEGIKMWAQAAAQBIREBIAeCARAEQCAAEAKkBCAAiYBBYAWBgEAAoBoWIEUAQgSEGRwVHKYEBEi0UE8lYAlF3sYYQhlFgBQKP6KjARKEAAAA.YAAAAAAAAAAA"
+      }
+    },
+    "site": {
+      "id": "57078628",
+      "domain": "www.affaritaliani.it",
+      "page": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html",
+      "ref": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html?refresh_ce",
+      "name": "www.affaritaliani.it",
+      "publisher": {
+        "id": "439696",
+        "name": "www.affaritaliani.it"
+      },
+      "cat": [
+        "IAB12"
+      ]
+    },
+    "publisher": {},
+    "cur": [
+      "USD"
+    ],
+    "bcat": [
+      "IAB12-2",
+      "IAB9-7"
+    ],
+    "imp": [{
+      "id": "1",
+      "bidfloor": 0.1,
+      "bidfloorcur": "USD",
+      "instl": 0,
+      "secure": 1,
+      "native": {
+        "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}",
+        "ver": "1.1"
+      },
+      "ext": {
+        "bidder": {
+          "key": "test_native"
+        }
+      }
+    }],
+    "regs": {
+      "ext": {
+        "gdpr": 1
+      }
+    }
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://service.e-volution.ai/pbserver",
+      "body": {
+        "id": "a1580f2f-be6d-11eb-a150-d094662c1c35",
+        "imp": [{
+          "id": "1",
+          "native": {
+            "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}",
+            "ver": "1.1"
+          },
+          "bidfloor": 0.1,
+          "bidfloorcur": "USD",
+          "secure": 1,
+          "ext": {
+            "bidder": {
+              "key": "test_native"
+            }
+          }
+        }],
+        "site": {
+          "id": "57078628",
+          "name": "www.affaritaliani.it",
+          "domain": "www.affaritaliani.it",
+          "cat": ["IAB12"],
+          "page": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html",
+          "ref": "https://www.affaritaliani.it/cronache/gestione-covid-proteste-di-imprenditori-sanitari-ma-ignorate-da-ogni-media-742138.html?refresh_ce",
+          "publisher": {
+            "id": "439696",
+            "name": "www.affaritaliani.it"
+          }
+        },
+        "device": {
+          "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
+          "geo": {
+            "country": "ITA"
+          },
+          "dnt": 0,
+          "ip": "79.26.58.249",
+          "devicetype": 2,
+          "os": "Mac OS",
+          "js": 1,
+          "language": "en"
+        },
+        "user": {
+          "id": "l1eHS1lZE41a",
+          "ext": {
+            "consent": "CPCfkEbPCfkEbERACAENBbCsAP_AAH_AAAAAHetf_X_fb39j-_59_9t0eY1f9_7_v-wzjhfds-8NyPvX_L8X42M7PF36pq4KuR4Eu3LBIQFlHOHUTUmw6okVrTPsak2Mr7NKJ7LEinMbe2dYGHtfn91TuZKYr_7s_9fz__-v_v__79f3r-3_3_vp9X---_e_V399xKB3QBJhqXwAWYljgSTRpVCiBCFYSHQCgAooBhaJrCAhYFOyuAj1BAwAQGoCMCIEGIKMWAQAAAQBIREBIAeCARAEQCAAEAKkBCAAiYBBYAWBgEAAoBoWIEUAQgSEGRwVHKYEBEi0UE8lYAlF3sYYQhlFgBQKP6KjARKEAAAA.YAAAAAAAAAAA"
+          }
+        },
+        "at": 1,
+        "tmax": 500,
+        "cur": ["USD"],
+        "bcat": ["IAB12-2", "IAB9-7"],
+        "regs": {
+          "ext": {
+            "gdpr": 1
+          }
+        }
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": {
+        "id": "a1580f2f-be6d-11eb-a150-d094662c1c35",
+        "bidid": "359da97d0384d8a14767029c18fd840d",
+        "seatbid": [],
+        "cur": "USD"
+      }
+    }
+  }],
+
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Empty seatbid",
+      "comparison": "literal"
+    }
+  ],
+
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/supplemental/status-204.json b/adapters/e_volution/evolutiontest/supplemental/status-204.json
new file mode 100644
index 00000000..85e89873
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/supplemental/status-204.json
@@ -0,0 +1,126 @@
+{
+  "mockBidRequest": {
+    "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+    "imp": [{
+      "id": "126365",
+      "secure": 1,
+      "bidfloor": 0.20,
+      "bidfloorcur": "USD",
+      "banner": {
+        "w": 300,
+        "h": 250,
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      },
+      "ext": {
+        "bidder": {
+          "key": "test_banner"
+        }
+      }
+    }],
+    "device": {
+      "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+      "geo": {
+        "country": "MEX",
+        "region": "CMX",
+        "city": "Mexico City",
+        "lat": 19.42,
+        "lon": -99.1663
+      },
+      "ip": "189.146.118.247",
+      "devicetype": 4,
+      "language": "it"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+      "ext": {
+        "consent": ""
+      }
+    },
+    "site": {
+      "id": "12",
+      "domain": "milano.repubblica.it",
+      "cat": ["IAB12"],
+      "page": "https://milano.repubblica.it",
+      "publisher": {
+        "id": "45672"
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "imp": [{
+            "id": "126365",
+            "banner": {
+              "format": [{
+                "w": 300,
+                "h": 250
+              }],
+              "w": 300,
+              "h": 250
+            },
+            "bidfloor": 0.2,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "ext": {
+              "bidder": {
+                "key": "test_banner"
+              }
+            }
+          }],
+          "site": {
+            "id": "12",
+            "domain": "milano.repubblica.it",
+            "cat": ["IAB12"],
+            "page": "https://milano.repubblica.it",
+            "publisher": {
+              "id": "45672"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+            "geo": {
+              "lat": 19.42,
+              "lon": -99.1663,
+              "country": "MEX",
+              "region": "CMX",
+              "city": "Mexico City"
+            },
+            "ip": "189.146.118.247",
+            "devicetype": 4,
+            "language": "it"
+          },
+          "user": {
+            "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+            "ext": {
+              "consent": ""
+            }
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 204,
+        "body": {}
+      }
+    }
+  ],
+
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/supplemental/status-400.json b/adapters/e_volution/evolutiontest/supplemental/status-400.json
new file mode 100644
index 00000000..b26e8272
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/supplemental/status-400.json
@@ -0,0 +1,133 @@
+{
+  "mockBidRequest": {
+    "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+    "imp": [{
+      "id": "126365",
+      "secure": 1,
+      "bidfloor": 0.20,
+      "bidfloorcur": "USD",
+      "banner": {
+        "w": 300,
+        "h": 250,
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      },
+      "ext": {
+        "bidder": {
+          "key": "45352"
+        }
+      }
+    }],
+    "device": {
+      "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+      "geo": {
+        "country": "MEX",
+        "region": "CMX",
+        "city": "Mexico City",
+        "lat": 19.42,
+        "lon": -99.1663
+      },
+      "ip": "189.146.118.247",
+      "devicetype": 4,
+      "language": "it"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+      "ext": {
+        "consent": ""
+      }
+    },
+    "site": {
+      "id": "12",
+      "domain": "milano.repubblica.it",
+      "cat": ["IAB12"],
+      "page": "https://milano.repubblica.it",
+      "publisher": {
+        "id": "45672"
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "imp": [{
+            "id": "126365",
+            "banner": {
+              "format": [{
+                "w": 300,
+                "h": 250
+              }],
+              "w": 300,
+              "h": 250
+            },
+            "bidfloor": 0.2,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "ext": {
+              "bidder": {
+                "key": "45352"
+              }
+            }
+          }],
+          "site": {
+            "id": "12",
+            "domain": "milano.repubblica.it",
+            "cat": ["IAB12"],
+            "page": "https://milano.repubblica.it",
+            "publisher": {
+              "id": "45672"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+            "geo": {
+              "lat": 19.42,
+              "lon": -99.1663,
+              "country": "MEX",
+              "region": "CMX",
+              "city": "Mexico City"
+            },
+            "ip": "189.146.118.247",
+            "devicetype": 4,
+            "language": "it"
+          },
+          "user": {
+            "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+            "ext": {
+              "consent": ""
+            }
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 400,
+        "body": "The Key has a different ad format"
+      }
+    }
+  ],
+
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad Request. \"The Key has a different ad format\"",
+      "comparison": "literal"
+    }
+  ],
+
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/supplemental/status-503.json b/adapters/e_volution/evolutiontest/supplemental/status-503.json
new file mode 100644
index 00000000..0f289ea8
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/supplemental/status-503.json
@@ -0,0 +1,125 @@
+{
+  "mockBidRequest": {
+    "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+    "imp": [{
+      "id": "126365",
+      "secure": 1,
+      "bidfloor": 0.20,
+      "bidfloorcur": "USD",
+      "banner": {
+        "w": 300,
+        "h": 250,
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      },
+      "ext": {
+        "bidder": {
+          "key": "45352"
+        }
+      }
+    }],
+    "device": {
+      "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+      "geo": {
+        "country": "MEX",
+        "region": "CMX",
+        "city": "Mexico City",
+        "lat": 19.42,
+        "lon": -99.1663
+      },
+      "ip": "189.146.118.247",
+      "devicetype": 4,
+      "language": "it"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+      "ext": {
+        "consent": ""
+      }
+    },
+    "site": {
+      "id": "12",
+      "domain": "milano.repubblica.it",
+      "cat": ["IAB12"],
+      "page": "https://milano.repubblica.it",
+      "publisher": {
+        "id": "45672"
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "imp": [{
+            "id": "126365",
+            "banner": {
+              "format": [{
+                "w": 300,
+                "h": 250
+              }],
+              "w": 300,
+              "h": 250
+            },
+            "bidfloor": 0.2,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "ext": {
+              "bidder": {
+                "key": "45352"
+              }
+            }
+          }],
+          "site": {
+            "id": "12",
+            "domain": "milano.repubblica.it",
+            "cat": ["IAB12"],
+            "page": "https://milano.repubblica.it",
+            "publisher": {
+              "id": "45672"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+            "geo": {
+              "lat": 19.42,
+              "lon": -99.1663,
+              "country": "MEX",
+              "region": "CMX",
+              "city": "Mexico City"
+            },
+            "ip": "189.146.118.247",
+            "devicetype": 4,
+            "language": "it"
+          },
+          "user": {
+            "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+            "ext": {
+              "consent": ""
+            }
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 503
+      }
+    }
+  ],
+
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/e_volution/evolutiontest/supplemental/unexpected-status.json b/adapters/e_volution/evolutiontest/supplemental/unexpected-status.json
new file mode 100644
index 00000000..5d0df323
--- /dev/null
+++ b/adapters/e_volution/evolutiontest/supplemental/unexpected-status.json
@@ -0,0 +1,132 @@
+{
+  "mockBidRequest": {
+    "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+    "imp": [{
+      "id": "126365",
+      "secure": 1,
+      "bidfloor": 0.20,
+      "bidfloorcur": "USD",
+      "banner": {
+        "w": 300,
+        "h": 250,
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      },
+      "ext": {
+        "bidder": {
+          "key": "45352"
+        }
+      }
+    }],
+    "device": {
+      "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+      "geo": {
+        "country": "MEX",
+        "region": "CMX",
+        "city": "Mexico City",
+        "lat": 19.42,
+        "lon": -99.1663
+      },
+      "ip": "189.146.118.247",
+      "devicetype": 4,
+      "language": "it"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+      "ext": {
+        "consent": ""
+      }
+    },
+    "site": {
+      "id": "12",
+      "domain": "milano.repubblica.it",
+      "cat": ["IAB12"],
+      "page": "https://milano.repubblica.it",
+      "publisher": {
+        "id": "45672"
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://service.e-volution.ai/pbserver",
+        "body": {
+          "id": "d910ceef496ff2d746176506e296f4b3_z53356_a126365",
+          "imp": [{
+            "id": "126365",
+            "banner": {
+              "format": [{
+                "w": 300,
+                "h": 250
+              }],
+              "w": 300,
+              "h": 250
+            },
+            "bidfloor": 0.2,
+            "bidfloorcur": "USD",
+            "secure": 1,
+            "ext": {
+              "bidder": {
+                "key": "45352"
+              }
+            }
+          }],
+          "site": {
+            "id": "12",
+            "domain": "milano.repubblica.it",
+            "cat": ["IAB12"],
+            "page": "https://milano.repubblica.it",
+            "publisher": {
+              "id": "45672"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1",
+            "geo": {
+              "lat": 19.42,
+              "lon": -99.1663,
+              "country": "MEX",
+              "region": "CMX",
+              "city": "Mexico City"
+            },
+            "ip": "189.146.118.247",
+            "devicetype": 4,
+            "language": "it"
+          },
+          "user": {
+            "id": "460ecf1d41fa6656c4b892fd84e61ff8c2ab5ad5",
+            "ext": {
+              "consent": ""
+            }
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 401
+      }
+    }
+  ],
+
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Something went wrong, please contact your Account Manager. Status Code: [ 401 ] ",
+      "comparison": "literal"
+    }
+  ],
+
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/e_volution/params_test.go b/adapters/e_volution/params_test.go
new file mode 100644
index 00000000..2d3602fd
--- /dev/null
+++ b/adapters/e_volution/params_test.go
@@ -0,0 +1,49 @@
+package evolution
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+var validParams = []string{
+	`{ "key": "24" }`,
+}
+
+func TestValidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json-schemas. %v", err)
+	}
+
+	for _, validParam := range validParams {
+		if err := validator.Validate(openrtb_ext.BidderEVolution, json.RawMessage(validParam)); err != nil {
+			t.Errorf("Schema rejected evolution params: %s", validParam)
+		}
+	}
+}
+
+var invalidParams = []string{
+	``,
+	`null`,
+	`true`,
+	`5`,
+	`4.2`,
+	`[]`,
+	`{}`,
+	`{ "anyparam": "anyvalue" }`,
+}
+
+func TestInvalidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json-schemas. %v", err)
+	}
+
+	for _, invalidParam := range invalidParams {
+		if err := validator.Validate(openrtb_ext.BidderEVolution, json.RawMessage(invalidParam)); err == nil {
+			t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+		}
+	}
+}
diff --git a/adapters/e_volution/usersync_test.go b/adapters/e_volution/usersync_test.go
new file mode 100644
index 00000000..d7a3eba5
--- /dev/null
+++ b/adapters/e_volution/usersync_test.go
@@ -0,0 +1,33 @@
+package evolution
+
+import (
+	"testing"
+	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/ccpa"
+	"github.com/prebid/prebid-server/privacy/gdpr"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestNewEvolutionSyncer(t *testing.T) {
+	syncURL := "https://sync.test.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+	syncer := NewEvolutionSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "0",
+			Consent: "allGdpr",
+		},
+		CCPA: ccpa.Policy{
+			Consent: "1---",
+		},
+	})
+
+	assert.NoError(t, err)
+	assert.Equal(t, "https://sync.test.com/pbserver?gdpr=0&gdpr_consent=allGdpr&ccpa=1---", syncInfo.URL)
+	assert.Equal(t, "redirect", syncInfo.Type)
+	assert.Equal(t, false, syncInfo.SupportCORS)
+}
diff --git a/adapters/lifestreet/lifestreet_test.go b/adapters/lifestreet/lifestreet_test.go
deleted file mode 100644
index 5c4f47fd..00000000
--- a/adapters/lifestreet/lifestreet_test.go
+++ /dev/null
@@ -1,291 +0,0 @@
-package lifestreet
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"io/ioutil"
-	"net/http"
-	"net/http/httptest"
-	"testing"
-	"time"
-
-	"github.com/mxmCherry/openrtb/v15/openrtb2"
-	"github.com/prebid/prebid-server/cache/dummycache"
-	"github.com/prebid/prebid-server/pbs"
-	"github.com/prebid/prebid-server/usersync"
-
-	"fmt"
-
-	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/config"
-)
-
-type lsTagInfo struct {
-	code    string
-	slotTag string
-	bid     float64
-	content string
-}
-
-type lsBidInfo struct {
-	appBundle            string
-	deviceIP             string
-	deviceUA             string
-	deviceMake           string
-	deviceModel          string
-	deviceConnectiontype int8
-	deviceIfa            string
-	tags                 []lsTagInfo
-	referrer             string
-	width                uint64
-	height               uint64
-	delay                time.Duration
-}
-
-var lsdata lsBidInfo
-
-func DummyLifestreetServer(w http.ResponseWriter, r *http.Request) {
-	defer r.Body.Close()
-	body, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-
-	var breq openrtb2.BidRequest
-	err = json.Unmarshal(body, &breq)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-
-	if breq.App == nil {
-		http.Error(w, fmt.Sprintf("No app object sent"), http.StatusInternalServerError)
-		return
-	}
-	if breq.App.Bundle != lsdata.appBundle {
-		http.Error(w, fmt.Sprintf("Bundle '%s' doesn't match '%s", breq.App.Bundle, lsdata.appBundle), http.StatusInternalServerError)
-		return
-	}
-	if breq.Device.UA != lsdata.deviceUA {
-		http.Error(w, fmt.Sprintf("UA '%s' doesn't match '%s", breq.Device.UA, lsdata.deviceUA), http.StatusInternalServerError)
-		return
-	}
-	if breq.Device.IP != lsdata.deviceIP {
-		http.Error(w, fmt.Sprintf("IP '%s' doesn't match '%s", breq.Device.IP, lsdata.deviceIP), http.StatusInternalServerError)
-		return
-	}
-	if breq.Device.Make != lsdata.deviceMake {
-		http.Error(w, fmt.Sprintf("Make '%s' doesn't match '%s", breq.Device.Make, lsdata.deviceMake), http.StatusInternalServerError)
-		return
-	}
-	if breq.Device.Model != lsdata.deviceModel {
-		http.Error(w, fmt.Sprintf("Model '%s' doesn't match '%s", breq.Device.Model, lsdata.deviceModel), http.StatusInternalServerError)
-		return
-	}
-	if *breq.Device.ConnectionType != openrtb2.ConnectionType(lsdata.deviceConnectiontype) {
-		http.Error(w, fmt.Sprintf("Connectiontype '%d' doesn't match '%d", breq.Device.ConnectionType, lsdata.deviceConnectiontype), http.StatusInternalServerError)
-		return
-	}
-	if breq.Device.IFA != lsdata.deviceIfa {
-		http.Error(w, fmt.Sprintf("IFA '%s' doesn't match '%s", breq.Device.IFA, lsdata.deviceIfa), http.StatusInternalServerError)
-		return
-	}
-	if len(breq.Imp) != 1 {
-		http.Error(w, fmt.Sprintf("Wrong number of imp objects sent: %d", len(breq.Imp)), http.StatusInternalServerError)
-		return
-	}
-	var bid *openrtb2.Bid
-	for _, tag := range lsdata.tags {
-		if breq.Imp[0].Banner == nil {
-			http.Error(w, fmt.Sprintf("No banner object sent"), http.StatusInternalServerError)
-			return
-		}
-		if *breq.Imp[0].Banner.W != int64(lsdata.width) || *breq.Imp[0].Banner.H != int64(lsdata.height) {
-			http.Error(w, fmt.Sprintf("Size '%dx%d' doesn't match '%dx%d", breq.Imp[0].Banner.W, breq.Imp[0].Banner.H, lsdata.width, lsdata.height), http.StatusInternalServerError)
-			return
-		}
-		if breq.Imp[0].TagID == tag.slotTag {
-			bid = &openrtb2.Bid{
-				ID:    "random-id",
-				ImpID: breq.Imp[0].ID,
-				Price: tag.bid,
-				AdM:   tag.content,
-				W:     int64(lsdata.width),
-				H:     int64(lsdata.height),
-			}
-		}
-	}
-	if bid == nil {
-		http.Error(w, fmt.Sprintf("Slot tag '%s' not found", breq.Imp[0].TagID), http.StatusInternalServerError)
-		return
-	}
-
-	resp := openrtb2.BidResponse{
-		ID:    "2345676337",
-		BidID: "975537589956",
-		Cur:   "USD",
-		SeatBid: []openrtb2.SeatBid{
-			{
-				Seat: "LSM",
-				Bid:  []openrtb2.Bid{*bid},
-			},
-		},
-	}
-
-	if lsdata.delay > 0 {
-		<-time.After(lsdata.delay)
-	}
-
-	js, err := json.Marshal(resp)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Write(js)
-}
-
-func TestLifestreetBasicResponse(t *testing.T) {
-	server := httptest.NewServer(http.HandlerFunc(DummyLifestreetServer))
-	defer server.Close()
-
-	lsdata = lsBidInfo{
-		appBundle:            "AppNexus.PrebidMobileDemo",
-		deviceIP:             "111.111.111.111",
-		deviceUA:             "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301",
-		deviceMake:           "Apple",
-		deviceModel:          "x86_64",
-		deviceConnectiontype: 1,
-		deviceIfa:            "6F3EA622-C2EE-4449-A97A-AE986D080C08",
-		tags:                 make([]lsTagInfo, 2),
-		referrer:             "http://test.com",
-		width:                320,
-		height:               480,
-	}
-	lsdata.tags[0] = lsTagInfo{
-		code:    "first-tag",
-		slotTag: "slot123.123",
-		bid:     2.44,
-	}
-	lsdata.tags[1] = lsTagInfo{
-		code:    "second-tag",
-		slotTag: "slot122.122",
-		bid:     1.11,
-	}
-
-	conf := *adapters.DefaultHTTPAdapterConfig
-	an := NewLifestreetLegacyAdapter(&conf, "https://prebid.s2s.lfstmedia.com/adrequest")
-	an.URI = server.URL
-
-	pbin := pbs.PBSRequest{
-		AdUnits: make([]pbs.AdUnit, 2),
-		App: &openrtb2.App{
-			Bundle: lsdata.appBundle,
-		},
-		Device: &openrtb2.Device{
-			UA:             lsdata.deviceUA,
-			IP:             lsdata.deviceIP,
-			Make:           lsdata.deviceMake,
-			Model:          lsdata.deviceModel,
-			ConnectionType: openrtb2.ConnectionType(lsdata.deviceConnectiontype).Ptr(),
-			IFA:            lsdata.deviceIfa,
-		},
-	}
-	for i, tag := range lsdata.tags {
-		pbin.AdUnits[i] = pbs.AdUnit{
-			Code: tag.code,
-			Sizes: []openrtb2.Format{
-				{
-					W: int64(lsdata.width),
-					H: int64(lsdata.height),
-				},
-			},
-			Bids: []pbs.Bids{
-				{
-					BidderCode: "lifestreet",
-					BidID:      fmt.Sprintf("random-id-from-pbjs-%d", i),
-					Params:     json.RawMessage(fmt.Sprintf("{\"slot_tag\": \"%s\"}", tag.slotTag)),
-				},
-			},
-		}
-	}
-
-	body := new(bytes.Buffer)
-	err := json.NewEncoder(body).Encode(pbin)
-	if err != nil {
-		t.Fatalf("Json encoding failed: %v", err)
-	}
-
-	fmt.Println("body", body)
-
-	req := httptest.NewRequest("POST", server.URL, body)
-	req.Header.Add("User-Agent", lsdata.deviceUA)
-	req.Header.Add("Referer", lsdata.referrer)
-	req.Header.Add("X-Real-IP", lsdata.deviceIP)
-
-	pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
-	fakewriter := httptest.NewRecorder()
-
-	pc.SetCookieOnResponse(fakewriter, false, &config.HostCookie{Domain: ""}, 90*24*time.Hour)
-	req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))
-
-	cacheClient, _ := dummycache.New()
-	hcc := config.HostCookie{}
-	pbReq, err := pbs.ParsePBSRequest(req, &config.AuctionTimeouts{
-		Default: 2000,
-		Max:     2000,
-	}, cacheClient, &hcc)
-	if err != nil {
-		t.Fatalf("ParsePBSRequest failed: %v", err)
-	}
-	if len(pbReq.Bidders) != 1 {
-		t.Fatalf("ParsePBSRequest returned %d bidders instead of 1", len(pbReq.Bidders))
-	}
-	if pbReq.Bidders[0].BidderCode != "lifestreet" {
-		t.Fatalf("ParsePBSRequest returned invalid bidder")
-	}
-
-	ctx := context.TODO()
-	bids, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err != nil {
-		t.Fatalf("Should not have gotten an error: %v", err)
-	}
-	if len(bids) != 2 {
-		t.Fatalf("Received %d bids instead of 2", len(bids))
-	}
-	for _, bid := range bids {
-		matched := false
-		for _, tag := range lsdata.tags {
-			if bid.AdUnitCode == tag.code {
-				matched = true
-				if bid.BidderCode != "lifestreet" {
-					t.Errorf("Incorrect BidderCode '%s'", bid.BidderCode)
-				}
-				if bid.Price != tag.bid {
-					t.Errorf("Incorrect bid price '%.2f' expected '%.2f'", bid.Price, tag.bid)
-				}
-				if bid.Width != int64(lsdata.width) || bid.Height != int64(lsdata.height) {
-					t.Errorf("Incorrect bid size %dx%d, expected %dx%d", bid.Width, bid.Height, lsdata.width, lsdata.height)
-				}
-				if bid.Adm != tag.content {
-					t.Errorf("Incorrect bid markup '%s' expected '%s'", bid.Adm, tag.content)
-				}
-			}
-		}
-		if !matched {
-			t.Errorf("Received bid for unknown ad unit '%s'", bid.AdUnitCode)
-		}
-	}
-
-	// same test but with request timing out
-	lsdata.delay = 5 * time.Millisecond
-	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)
-	defer cancel()
-
-	bids, err = an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err == nil {
-		t.Fatalf("Should have gotten a timeout error: %v", err)
-	}
-}
diff --git a/adapters/lifestreet/lifestreettest/params/race/banner.json b/adapters/lifestreet/lifestreettest/params/race/banner.json
deleted file mode 100644
index c746cc15..00000000
--- a/adapters/lifestreet/lifestreettest/params/race/banner.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "slot_tag": "slot166704"
-}
diff --git a/adapters/lifestreet/lifestreettest/params/race/video.json b/adapters/lifestreet/lifestreettest/params/race/video.json
deleted file mode 100644
index 7103cf63..00000000
--- a/adapters/lifestreet/lifestreettest/params/race/video.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "slot_tag": "slot1227631"
-}
diff --git a/adapters/lifestreet/usersync_test.go b/adapters/lifestreet/usersync_test.go
deleted file mode 100644
index e41217fe..00000000
--- a/adapters/lifestreet/usersync_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package lifestreet
-
-import (
-	"testing"
-	"text/template"
-
-	"github.com/prebid/prebid-server/privacy"
-	"github.com/prebid/prebid-server/privacy/gdpr"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestLifestreetSyncer(t *testing.T) {
-	syncURL := "//ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl=localhost%2Fsetuid%3Fbidder%3Dlifestreet%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%24visitor_cookie%24%24"
-	syncURLTemplate := template.Must(
-		template.New("sync-template").Parse(syncURL),
-	)
-
-	syncer := NewLifestreetSyncer(syncURLTemplate)
-	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
-		GDPR: gdpr.Policy{
-			Signal: "0",
-		},
-	})
-
-	assert.NoError(t, err)
-	assert.Equal(t, "//ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl=localhost%2Fsetuid%3Fbidder%3Dlifestreet%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24%24visitor_cookie%24%24", syncInfo.URL)
-	assert.Equal(t, "redirect", syncInfo.Type)
-	assert.Equal(t, false, syncInfo.SupportCORS)
-}
diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go
index 561b4ed7..7632894b 100644
--- a/endpoints/cookie_sync_test.go
+++ b/endpoints/cookie_sync_test.go
@@ -13,7 +13,6 @@ import (
 	"github.com/julienschmidt/httprouter"
 	"github.com/prebid/prebid-server/adapters/appnexus"
 	"github.com/prebid/prebid-server/adapters/audienceNetwork"
-	"github.com/prebid/prebid-server/adapters/lifestreet"
 	"github.com/prebid/prebid-server/adapters/pubmatic"
 	analyticsConf "github.com/prebid/prebid-server/analytics/config"
 	"github.com/prebid/prebid-server/config"
@@ -41,12 +40,12 @@ func TestGDPRPreventsCookie(t *testing.T) {
 }
 
 func TestGDPRPreventsBidders(t *testing.T) {
-	rr := doPost(`{"gdpr":1,"bidders":["appnexus", "pubmatic", "lifestreet"],"gdpr_consent":"BOONs2HOONs2HABABBENAGgAAAAPrABACGA"}`, nil, true, map[openrtb_ext.BidderName]usersync.Usersyncer{
-		openrtb_ext.BidderLifestreet: lifestreet.NewLifestreetSyncer(template.Must(template.New("sync").Parse("someurl.com"))),
+	rr := doPost(`{"gdpr":1,"bidders":["appnexus", "pubmatic"],"gdpr_consent":"BOONs2HOONs2HABABBENAGgAAAAPrABACGA"}`, nil, true, map[openrtb_ext.BidderName]usersync.Usersyncer{
+		openrtb_ext.BidderPubmatic: pubmatic.NewPubmaticSyncer(template.Must(template.New("sync").Parse("someurl.com"))),
 	})
 	assert.Equal(t, rr.Header().Get("Content-Type"), "application/json; charset=utf-8")
 	assert.Equal(t, http.StatusOK, rr.Code)
-	assert.ElementsMatch(t, []string{"lifestreet"}, parseSyncs(t, rr.Body.Bytes()))
+	assert.ElementsMatch(t, []string{"pubmatic"}, parseSyncs(t, rr.Body.Bytes()))
 	assert.Equal(t, "no_cookie", parseStatus(t, rr.Body.Bytes()))
 }
 
@@ -145,7 +144,7 @@ func TestCookieSyncNoBidders(t *testing.T) {
 	rr := doPost("{}", nil, true, syncersForTest())
 	assert.Equal(t, rr.Header().Get("Content-Type"), "application/json; charset=utf-8")
 	assert.Equal(t, http.StatusOK, rr.Code)
-	assert.ElementsMatch(t, []string{"appnexus", "audienceNetwork", "lifestreet", "pubmatic"}, parseSyncs(t, rr.Body.Bytes()))
+	assert.ElementsMatch(t, []string{"appnexus", "audienceNetwork", "pubmatic"}, parseSyncs(t, rr.Body.Bytes()))
 	assert.Equal(t, "no_cookie", parseStatus(t, rr.Body.Bytes()))
 }
 
@@ -203,7 +202,6 @@ func syncersForTest() map[openrtb_ext.BidderName]usersync.Usersyncer {
 	return map[openrtb_ext.BidderName]usersync.Usersyncer{
 		openrtb_ext.BidderAppnexus:        appnexus.NewAppnexusSyncer(template.Must(template.New("sync").Parse("someurl.com"))),
 		openrtb_ext.BidderAudienceNetwork: audienceNetwork.NewFacebookSyncer(template.Must(template.New("sync").Parse("https://www.facebook.com/audiencenetwork/idsync/?partner=partnerId&callback=localhost%2Fsetuid%3Fbidder%3DaudienceNetwork%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))),
-		openrtb_ext.BidderLifestreet:      lifestreet.NewLifestreetSyncer(template.Must(template.New("sync").Parse("anotherurl.com"))),
 		openrtb_ext.BidderPubmatic:        pubmatic.NewPubmaticSyncer(template.Must(template.New("sync").Parse("thaturl.com"))),
 	}
 }
diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go
index c9f1907d..a8e8ef5e 100644
--- a/exchange/adapter_util_test.go
+++ b/exchange/adapter_util_test.go
@@ -1,7 +1,6 @@
 package exchange
 
 import (
-	"context"
 	"errors"
 	"net/http"
 	"testing"
@@ -9,10 +8,8 @@ import (
 	"github.com/mxmCherry/openrtb/v15/openrtb2"
 	"github.com/prebid/prebid-server/adapters"
 	"github.com/prebid/prebid-server/adapters/appnexus"
-	"github.com/prebid/prebid-server/adapters/lifestreet"
 	"github.com/prebid/prebid-server/adapters/rubicon"
 	"github.com/prebid/prebid-server/config"
-	"github.com/prebid/prebid-server/currency"
 	metrics "github.com/prebid/prebid-server/metrics/config"
 	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/stretchr/testify/assert"
@@ -23,64 +20,19 @@ var (
 	infoDisabled = config.BidderInfo{Enabled: false}
 )
 
-func TestBuildAdaptersSuccess(t *testing.T) {
-	client := &http.Client{}
-	cfg := &config.Configuration{Adapters: map[string]config.Adapter{
-		"appnexus":   {},
-		"lifestreet": {Endpoint: "anyEndpoint"},
-	}}
-	infos := map[string]config.BidderInfo{
-		"appnexus":   infoEnabled,
-		"lifestreet": infoEnabled,
-	}
-	metricEngine := &metrics.DummyMetricsEngine{}
-
-	bidders, errs := BuildAdapters(client, cfg, infos, metricEngine)
-
-	appnexusBidder, _ := appnexus.Builder(openrtb_ext.BidderAppnexus, config.Adapter{})
-	appnexusBidderWithInfo := adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled)
-	appnexusBidderAdapted := adaptBidder(appnexusBidderWithInfo, client, &config.Configuration{}, metricEngine, openrtb_ext.BidderAppnexus, nil)
-	appnexusBidderValidated := addValidatedBidderMiddleware(appnexusBidderAdapted)
-
-	idLegacyAdapted := &adaptedAdapter{lifestreet.NewLifestreetLegacyAdapter(adapters.DefaultHTTPAdapterConfig, "anyEndpoint")}
-	idLegacyValidated := addValidatedBidderMiddleware(idLegacyAdapted)
-
-	expectedBidders := map[openrtb_ext.BidderName]adaptedBidder{
-		openrtb_ext.BidderAppnexus:   appnexusBidderValidated,
-		openrtb_ext.BidderLifestreet: idLegacyValidated,
-	}
-
-	assert.Equal(t, expectedBidders, bidders)
-	assert.Empty(t, errs)
-}
-
-func TestBuildAdaptersErrors(t *testing.T) {
-	client := &http.Client{}
-	cfg := &config.Configuration{Adapters: map[string]config.Adapter{"unknown": {}}}
-	infos := map[string]config.BidderInfo{}
-	metricEngine := &metrics.DummyMetricsEngine{}
-
-	bidders, errs := BuildAdapters(client, cfg, infos, metricEngine)
-
-	expectedErrors := []error{
-		errors.New("unknown: unknown bidder"),
-	}
-
-	assert.Empty(t, bidders)
-	assert.Equal(t, expectedErrors, errs)
-}
-
-func TestBuildExchangeBidders(t *testing.T) {
+func TestBuildAdapters(t *testing.T) {
 	client := &http.Client{}
 	metricEngine := &metrics.DummyMetricsEngine{}
 
 	appnexusBidder, _ := appnexus.Builder(openrtb_ext.BidderAppnexus, config.Adapter{})
 	appnexusBidderWithInfo := adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled)
 	appnexusBidderAdapted := adaptBidder(appnexusBidderWithInfo, client, &config.Configuration{}, metricEngine, openrtb_ext.BidderAppnexus, nil)
+	appnexusValidated := addValidatedBidderMiddleware(appnexusBidderAdapted)
 
 	rubiconBidder, _ := rubicon.Builder(openrtb_ext.BidderRubicon, config.Adapter{})
 	rubiconBidderWithInfo := adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled)
 	rubiconBidderAdapted := adaptBidder(rubiconBidderWithInfo, client, &config.Configuration{}, metricEngine, openrtb_ext.BidderRubicon, nil)
+	rubiconbidderValidated := addValidatedBidderMiddleware(rubiconBidderAdapted)
 
 	testCases := []struct {
 		description     string
@@ -90,42 +42,42 @@ func TestBuildExchangeBidders(t *testing.T) {
 		expectedErrors  []error
 	}{
 		{
-			description:   "Invalid - Builder Errors",
-			adapterConfig: map[string]config.Adapter{"appnexus": {}, "unknown": {}},
-			bidderInfos:   map[string]config.BidderInfo{},
-			expectedErrors: []error{
-				errors.New("appnexus: bidder info not found"),
-				errors.New("unknown: unknown bidder"),
-			},
-		},
-		{
-			description:     "Success - None",
+			description:     "No Bidders",
 			adapterConfig:   map[string]config.Adapter{},
 			bidderInfos:     map[string]config.BidderInfo{},
 			expectedBidders: map[openrtb_ext.BidderName]adaptedBidder{},
 		},
 		{
-			description:   "Success - One",
+			description:   "One Bidder",
 			adapterConfig: map[string]config.Adapter{"appnexus": {}},
 			bidderInfos:   map[string]config.BidderInfo{"appnexus": infoEnabled},
 			expectedBidders: map[openrtb_ext.BidderName]adaptedBidder{
-				openrtb_ext.BidderAppnexus: appnexusBidderAdapted,
+				openrtb_ext.BidderAppnexus: appnexusValidated,
 			},
 		},
 		{
-			description:   "Success - Many",
+			description:   "Many Bidders",
 			adapterConfig: map[string]config.Adapter{"appnexus": {}, "rubicon": {}},
 			bidderInfos:   map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled},
 			expectedBidders: map[openrtb_ext.BidderName]adaptedBidder{
-				openrtb_ext.BidderAppnexus: appnexusBidderAdapted,
-				openrtb_ext.BidderRubicon:  rubiconBidderAdapted,
+				openrtb_ext.BidderAppnexus: appnexusValidated,
+				openrtb_ext.BidderRubicon:  rubiconbidderValidated,
+			},
+		},
+		{
+			description:   "Invalid - Builder Errors",
+			adapterConfig: map[string]config.Adapter{"appnexus": {}, "unknown": {}},
+			bidderInfos:   map[string]config.BidderInfo{},
+			expectedErrors: []error{
+				errors.New("appnexus: bidder info not found"),
+				errors.New("unknown: unknown bidder"),
 			},
 		},
 	}
 
 	for _, test := range testCases {
 		cfg := &config.Configuration{Adapters: test.adapterConfig}
-		bidders, errs := buildExchangeBidders(cfg, test.bidderInfos, client, metricEngine)
+		bidders, errs := BuildAdapters(client, cfg, test.bidderInfos, metricEngine)
 		assert.Equal(t, test.expectedBidders, bidders, test.description+":bidders")
 		assert.ElementsMatch(t, test.expectedErrors, errs, test.description+":errors")
 	}
@@ -139,8 +91,6 @@ func TestBuildBidders(t *testing.T) {
 	rubiconBidder := fakeBidder{"b"}
 	rubiconBuilder := fakeBuilder{rubiconBidder, nil}.Builder
 
-	inconsequentialBuilder := fakeBuilder{fakeBidder{"whatevs"}, nil}.Builder
-
 	testCases := []struct {
 		description     string
 		adapterConfig   map[string]config.Adapter
@@ -210,15 +160,6 @@ func TestBuildBidders(t *testing.T) {
 				openrtb_ext.BidderRubicon:  adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled),
 			},
 		},
-		{
-			description:   "Success - Ignores Legacy",
-			adapterConfig: map[string]config.Adapter{"appnexus": {}, "lifestreet": {}},
-			bidderInfos:   map[string]config.BidderInfo{"appnexus": infoEnabled, "lifestreet": infoEnabled},
-			builders:      map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderLifestreet: inconsequentialBuilder},
-			expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{
-				openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled),
-			},
-		},
 		{
 			description:   "Success - Ignores Disabled",
 			adapterConfig: map[string]config.Adapter{"appnexus": {}, "rubicon": {}},
@@ -252,53 +193,6 @@ func TestBuildBidders(t *testing.T) {
 	}
 }
 
-func TestBuildExchangeBiddersLegacy(t *testing.T) {
-	cfg := config.Adapter{Endpoint: "anyEndpoint"}
-
-	expectedLifestreet := &adaptedAdapter{lifestreet.NewLifestreetLegacyAdapter(adapters.DefaultHTTPAdapterConfig, "anyEndpoint")}
-
-	testCases := []struct {
-		description   string
-		adapterConfig map[string]config.Adapter
-		bidderInfos   map[string]config.BidderInfo
-		expected      map[openrtb_ext.BidderName]adaptedBidder
-	}{
-		{
-			description:   "Active",
-			adapterConfig: map[string]config.Adapter{"lifestreet": cfg},
-			bidderInfos:   map[string]config.BidderInfo{"lifestreet": infoEnabled},
-			expected:      map[openrtb_ext.BidderName]adaptedBidder{"lifestreet": expectedLifestreet},
-		},
-		{
-			description:   "Disabled",
-			adapterConfig: map[string]config.Adapter{"lifestreet": cfg},
-			bidderInfos:   map[string]config.BidderInfo{"lifestreet": infoDisabled},
-			expected:      map[openrtb_ext.BidderName]adaptedBidder{},
-		},
-	}
-
-	for _, test := range testCases {
-		result := buildExchangeBiddersLegacy(test.adapterConfig, test.bidderInfos)
-		assert.Equal(t, test.expected, result, test.description)
-	}
-}
-
-func TestWrapWithMiddleware(t *testing.T) {
-	appNexusBidder := fakeAdaptedBidder{}
-
-	bidders := map[openrtb_ext.BidderName]adaptedBidder{
-		openrtb_ext.BidderAppnexus: appNexusBidder,
-	}
-
-	wrapWithMiddleware(bidders)
-
-	expected := map[openrtb_ext.BidderName]adaptedBidder{
-		openrtb_ext.BidderAppnexus: &validatedBidder{appNexusBidder},
-	}
-
-	assert.Equal(t, expected, bidders)
-}
-
 func TestGetActiveBidders(t *testing.T) {
 	testCases := []struct {
 		description string
@@ -342,24 +236,32 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 		{
 			description: "None",
 			bidderInfos: map[string]config.BidderInfo{},
-			expected:    map[string]string{},
+			expected: map[string]string{
+				"lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
+			},
 		},
 		{
 			description: "Enabled",
 			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
-			expected:    map[string]string{},
+			expected: map[string]string{
+				"lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
+			},
 		},
 		{
 			description: "Disabled",
 			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled},
 			expected: map[string]string{
-				"appnexus": `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`,
+				"lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
+				"appnexus":   `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`,
 			},
 		},
 		{
 			description: "Mixed",
 			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled, "openx": infoEnabled},
-			expected:    map[string]string{"appnexus": `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`},
+			expected: map[string]string{
+				"lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
+				"appnexus":   `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`,
+			},
 		},
 	}
 
@@ -369,12 +271,6 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 	}
 }
 
-type fakeAdaptedBidder struct{}
-
-func (fakeAdaptedBidder) requestBid(ctx context.Context, request *openrtb2.BidRequest, name openrtb_ext.BidderName, bidAdjustment float64, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, accountDebugAllowed bool) (*pbsOrtbSeatBid, []error) {
-	return nil, nil
-}
-
 type fakeBidder struct {
 	name string
 }
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index a03c4786..d3bcf082 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -2623,26 +2623,42 @@ func TestCategoryMappingTwoBiddersManyBidsEachNoCategorySamePrice(t *testing.T)
 
 	totalNumberOfbids := 0
 
+	//due to random map order we need to identify what bidder was first
+	firstBidderIndicator := true
+
 	if bidsFromFirstBidder.bids != nil {
 		totalNumberOfbids += len(bidsFromFirstBidder.bids)
 	}
 
 	if bidsFromSecondBidder.bids != nil {
+		firstBidderIndicator = false
 		totalNumberOfbids += len(bidsFromSecondBidder.bids)
 	}
 
 	assert.Equal(t, 2, totalNumberOfbids, "2 bids total should be returned")
+	assert.Len(t, rejections, 2, "2 bids should be de-duplicated")
 
-	assert.Len(t, adapterBids[bidderNameApn1].bids, 0)
-	assert.Len(t, adapterBids[bidderNameApn2].bids, 2)
+	if firstBidderIndicator {
+		assert.Len(t, adapterBids[bidderNameApn1].bids, 2)
+		assert.Len(t, adapterBids[bidderNameApn2].bids, 0)
 
-	assert.Equal(t, "bid_idApn2_1", adapterBids[bidderNameApn2].bids[0].bid.ID, "Incorrect expected bid 1 id")
-	assert.Equal(t, "bid_idApn2_2", adapterBids[bidderNameApn2].bids[1].bid.ID, "Incorrect expected bid 2 id")
+		assert.Equal(t, "bid_idApn1_1", adapterBids[bidderNameApn1].bids[0].bid.ID, "Incorrect expected bid 1 id")
+		assert.Equal(t, "bid_idApn1_2", adapterBids[bidderNameApn1].bids[1].bid.ID, "Incorrect expected bid 2 id")
 
-	assert.Len(t, rejections, 2, "2 bids should be de-duplicated")
-	assert.Equal(t, "bid rejected [bid ID: bid_idApn1_1] reason: Bid was deduplicated", rejections[0], "Incorrect rejected bid 1")
-	assert.Equal(t, "bid rejected [bid ID: bid_idApn1_2] reason: Bid was deduplicated", rejections[1], "Incorrect rejected bid 2")
+		assert.Equal(t, "bid rejected [bid ID: bid_idApn2_1] reason: Bid was deduplicated", rejections[0], "Incorrect rejected bid 1")
+		assert.Equal(t, "bid rejected [bid ID: bid_idApn2_2] reason: Bid was deduplicated", rejections[1], "Incorrect rejected bid 2")
+
+	} else {
+		assert.Len(t, adapterBids[bidderNameApn1].bids, 0)
+		assert.Len(t, adapterBids[bidderNameApn2].bids, 2)
+
+		assert.Equal(t, "bid_idApn2_1", adapterBids[bidderNameApn2].bids[0].bid.ID, "Incorrect expected bid 1 id")
+		assert.Equal(t, "bid_idApn2_2", adapterBids[bidderNameApn2].bids[1].bid.ID, "Incorrect expected bid 2 id")
 
+		assert.Equal(t, "bid rejected [bid ID: bid_idApn1_1] reason: Bid was deduplicated", rejections[0], "Incorrect rejected bid 1")
+		assert.Equal(t, "bid rejected [bid ID: bid_idApn1_2] reason: Bid was deduplicated", rejections[1], "Incorrect rejected bid 2")
+
+	}
 }
 
 func TestRemoveBidById(t *testing.T) {
diff --git a/exchange/legacy_test.go b/exchange/legacy_test.go
deleted file mode 100644
index cbb5fda4..00000000
--- a/exchange/legacy_test.go
+++ /dev/null
@@ -1,505 +0,0 @@
-package exchange
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-	"net/http"
-	"reflect"
-	"testing"
-	"time"
-
-	"github.com/buger/jsonparser"
-	jsonpatch "github.com/evanphx/json-patch"
-	"github.com/mxmCherry/openrtb/v15/openrtb2"
-	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/currency"
-	"github.com/prebid/prebid-server/openrtb_ext"
-	"github.com/prebid/prebid-server/pbs"
-	"github.com/prebid/prebid-server/usersync"
-)
-
-func TestSiteVideo(t *testing.T) {
-	ortbRequest := &openrtb2.BidRequest{
-		ID:   "request-id",
-		TMax: 1000,
-		Site: &openrtb2.Site{
-			Page:   "http://www.site.com",
-			Domain: "site.com",
-			Publisher: &openrtb2.Publisher{
-				ID: "b1c81a38-1415-42b7-8238-0d2d64016c27",
-			},
-		},
-		Source: &openrtb2.Source{
-			TID: "transaction-id",
-		},
-		User: &openrtb2.User{
-			ID:       "host-id",
-			BuyerUID: "bidder-id",
-		},
-		Test: 1,
-		Imp: []openrtb2.Imp{{
-			ID: "imp-id",
-			Video: &openrtb2.Video{
-				MIMEs:       []string{"video/mp4"},
-				MinDuration: 20,
-				MaxDuration: 40,
-				Protocols:   []openrtb2.Protocol{openrtb2.ProtocolVAST10},
-				StartDelay:  openrtb2.StartDelayGenericMidRoll.Ptr(),
-			},
-			Banner: &openrtb2.Banner{
-				Format: []openrtb2.Format{{
-					W: 300,
-					H: 250,
-				}},
-			},
-			Ext: json.RawMessage(`{"bidder":{"cp":512379,"ct":486653,"cf":"300x250"}}`),
-		}},
-	}
-
-	mockAdapter := mockLegacyAdapter{}
-
-	exchangeBidder := adaptLegacyAdapter(&mockAdapter)
-	currencyConverter := currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
-	_, errs := exchangeBidder.requestBid(context.Background(), ortbRequest, openrtb_ext.BidderRubicon, 1.0, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, true)
-	if len(errs) > 0 {
-		t.Errorf("Unexpected error requesting bids: %v", errs)
-	}
-
-	if mockAdapter.gotRequest == nil {
-		t.Fatalf("Mock adapter never received a request.")
-	}
-
-	if mockAdapter.gotBidder == nil {
-		t.Fatalf("Mock adapter never received a bidder.")
-	}
-
-	assertEquivalentRequests(t, ortbRequest, mockAdapter.gotRequest)
-
-	if mockAdapter.gotBidder.BidderCode != string(openrtb_ext.BidderRubicon) {
-		t.Errorf("Wrong bidder code. Expected %s, got %s", string(openrtb_ext.BidderRubicon), mockAdapter.gotBidder.BidderCode)
-	}
-	assertEquivalentBidder(t, ortbRequest, mockAdapter.gotBidder)
-}
-
-func TestAppBanner(t *testing.T) {
-	ortbRequest := newAppOrtbRequest()
-	ortbRequest.TMax = 1000
-	ortbRequest.User = &openrtb2.User{
-		ID:       "host-id",
-		BuyerUID: "bidder-id",
-	}
-	ortbRequest.Test = 1
-
-	mockAdapter := mockLegacyAdapter{}
-
-	exchangeBidder := adaptLegacyAdapter(&mockAdapter)
-	currencyConverter := currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
-	_, errs := exchangeBidder.requestBid(context.Background(), ortbRequest, openrtb_ext.BidderRubicon, 1.0, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, true)
-	if len(errs) > 0 {
-		t.Errorf("Unexpected error requesting bids: %v", errs)
-	}
-
-	if mockAdapter.gotRequest == nil {
-		t.Fatalf("Mock adapter never received a request.")
-	}
-
-	if mockAdapter.gotBidder == nil {
-		t.Fatalf("Mock adapter never received a bidder.")
-	}
-	if mockAdapter.gotBidder.BidderCode != string(openrtb_ext.BidderRubicon) {
-		t.Errorf("Wrong bidder code. Expected %s, got %s", string(openrtb_ext.BidderRubicon), mockAdapter.gotBidder.BidderCode)
-	}
-
-	assertEquivalentRequests(t, ortbRequest, mockAdapter.gotRequest)
-	assertEquivalentBidder(t, ortbRequest, mockAdapter.gotBidder)
-}
-
-func TestBidTransforms(t *testing.T) {
-	bidAdjustment := 0.3
-	initialBidPrice := 0.5
-	legalBid := &pbs.PBSBid{
-		BidID:             "bid-1",
-		AdUnitCode:        "adunit-1",
-		Creative_id:       "creative-1",
-		CreativeMediaType: "banner",
-		Price:             initialBidPrice,
-		NURL:              "nurl",
-		Adm:               "ad-markup",
-		Width:             10,
-		Height:            20,
-		DealId:            "some-deal",
-	}
-	mockAdapter := mockLegacyAdapter{
-		returnedBids: pbs.PBSBidSlice{
-			legalBid,
-			&pbs.PBSBid{
-				CreativeMediaType: "unsupported",
-			},
-		},
-	}
-
-	exchangeBidder := adaptLegacyAdapter(&mockAdapter)
-	currencyConverter := currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
-	seatBid, errs := exchangeBidder.requestBid(context.Background(), newAppOrtbRequest(), openrtb_ext.BidderRubicon, bidAdjustment, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, true)
-	if len(errs) != 1 {
-		t.Fatalf("Bad error count. Expected 1, got %d", len(errs))
-	}
-	if errs[0].Error() != "invalid BidType: unsupported" {
-		t.Errorf("Unexpected error message. Got %s", errs[0].Error())
-	}
-
-	if len(seatBid.bids) != 1 {
-		t.Fatalf("Bad bid count. Expected 1, got %d", len(seatBid.bids))
-	}
-	theBid := seatBid.bids[0]
-	if theBid.bidType != openrtb_ext.BidTypeBanner {
-		t.Errorf("Bad BidType. Expected banner, got %s", theBid.bidType)
-	}
-	if theBid.bid.ID != legalBid.BidID {
-		t.Errorf("Bad id. Expected %s, got %s", legalBid.NURL, theBid.bid.NURL)
-	}
-	if theBid.bid.ImpID != legalBid.AdUnitCode {
-		t.Errorf("Bad impid. Expected %s, got %s", legalBid.AdUnitCode, theBid.bid.ImpID)
-	}
-	if theBid.bid.CrID != legalBid.Creative_id {
-		t.Errorf("Bad creativeid. Expected %s, got %s", legalBid.Creative_id, theBid.bid.CrID)
-	}
-	if theBid.bid.Price != initialBidPrice*bidAdjustment {
-		t.Errorf("Bad price. Expected %f, got %f", initialBidPrice*bidAdjustment, theBid.bid.Price)
-	}
-	if theBid.bid.NURL != legalBid.NURL {
-		t.Errorf("Bad NURL. Expected %s, got %s", legalBid.NURL, theBid.bid.NURL)
-	}
-	if theBid.bid.AdM != legalBid.Adm {
-		t.Errorf("Bad adm. Expected %s, got %s", legalBid.Adm, theBid.bid.AdM)
-	}
-	if theBid.bid.W != legalBid.Width {
-		t.Errorf("Bad adm. Expected %d, got %d", legalBid.Width, theBid.bid.W)
-	}
-	if theBid.bid.H != legalBid.Height {
-		t.Errorf("Bad adm. Expected %d, got %d", legalBid.Height, theBid.bid.H)
-	}
-	if theBid.bid.DealID != legalBid.DealId {
-		t.Errorf("Bad dealid. Expected %s, got %s", legalBid.DealId, theBid.bid.DealID)
-	}
-}
-
-func TestInsecureImps(t *testing.T) {
-	insecure := int8(0)
-	bidReq := &openrtb2.BidRequest{
-		Imp: []openrtb2.Imp{{
-			Secure: &insecure,
-		}, {
-			Secure: &insecure,
-		}},
-	}
-	isSecure, err := toSecure(bidReq)
-	if err != nil {
-		t.Errorf("Unexpected error: %v", err)
-	}
-	if isSecure != 0 {
-		t.Errorf("Final request should be insecure. Got %d", isSecure)
-	}
-}
-
-func TestSecureImps(t *testing.T) {
-	secure := int8(1)
-	bidReq := &openrtb2.BidRequest{
-		Imp: []openrtb2.Imp{{
-			Secure: &secure,
-		}, {
-			Secure: &secure,
-		}},
-	}
-	isSecure, err := toSecure(bidReq)
-	if err != nil {
-		t.Errorf("Unexpected error: %v", err)
-	}
-	if isSecure != 1 {
-		t.Errorf("Final request should be secure. Got %d", isSecure)
-	}
-}
-
-func TestMixedSecureImps(t *testing.T) {
-	insecure := int8(0)
-	secure := int8(1)
-	bidReq := &openrtb2.BidRequest{
-		Imp: []openrtb2.Imp{{
-			Secure: &insecure,
-		}, {
-			Secure: &secure,
-		}},
-	}
-	_, err := toSecure(bidReq)
-	if err == nil {
-		t.Error("No error was received, but we should have gotten one.")
-	}
-}
-
-func newAppOrtbRequest() *openrtb2.BidRequest {
-	return &openrtb2.BidRequest{
-		ID: "request-id",
-		App: &openrtb2.App{
-			Publisher: &openrtb2.Publisher{
-				ID: "b1c81a38-1415-42b7-8238-0d2d64016c27",
-			},
-		},
-		Source: &openrtb2.Source{
-			TID: "transaction-id",
-		},
-		Imp: []openrtb2.Imp{{
-			ID: "imp-id",
-			Banner: &openrtb2.Banner{
-				Format: []openrtb2.Format{{
-					W: 300,
-					H: 250,
-				}},
-			},
-			Ext: json.RawMessage(`{"bidder":{"cp":512379,"ct":486653,"cf":"300x250"}}`),
-		}},
-	}
-}
-
-func TestErrorResponse(t *testing.T) {
-	ortbRequest := &openrtb2.BidRequest{
-		ID: "request-id",
-		App: &openrtb2.App{
-			Publisher: &openrtb2.Publisher{
-				ID: "b1c81a38-1415-42b7-8238-0d2d64016c27",
-			},
-		},
-		Source: &openrtb2.Source{
-			TID: "transaction-id",
-		},
-		Imp: []openrtb2.Imp{{
-			ID: "imp-id",
-			Banner: &openrtb2.Banner{
-				Format: []openrtb2.Format{{
-					W: 300,
-					H: 250,
-				}},
-			},
-			Ext: json.RawMessage(`{"bidder":{"cp":512379,"ct":486653,"cf":"300x250"}}`),
-		}},
-	}
-
-	mockAdapter := mockLegacyAdapter{
-		returnedError: errors.New("adapter failed"),
-	}
-
-	exchangeBidder := adaptLegacyAdapter(&mockAdapter)
-	currencyConverter := currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
-	_, errs := exchangeBidder.requestBid(context.Background(), ortbRequest, openrtb_ext.BidderRubicon, 1.0, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, true)
-	if len(errs) != 1 {
-		t.Fatalf("Bad error count. Expected 1, got %d", len(errs))
-	}
-	if errs[0].Error() != "adapter failed" {
-		t.Errorf("Unexpected error message. Got %s", errs[0].Error())
-	}
-}
-
-func TestWithTargeting(t *testing.T) {
-	ortbRequest := &openrtb2.BidRequest{
-		ID: "request-id",
-		App: &openrtb2.App{
-			Publisher: &openrtb2.Publisher{
-				ID: "b1c81a38-1415-42b7-8238-0d2d64016c27",
-			},
-		},
-		Source: &openrtb2.Source{
-			TID: "transaction-id",
-		},
-		Imp: []openrtb2.Imp{{
-			ID: "imp-id",
-			Banner: &openrtb2.Banner{
-				Format: []openrtb2.Format{{
-					W: 300,
-					H: 250,
-				}},
-			},
-			Ext: json.RawMessage(`{"bidder": {"placementId": "1959066997713356_1959836684303054"}}`),
-		}},
-	}
-
-	mockAdapter := mockLegacyAdapter{
-		returnedBids: []*pbs.PBSBid{{
-			CreativeMediaType: "banner",
-		}},
-	}
-	exchangeBidder := adaptLegacyAdapter(&mockAdapter)
-	currencyConverter := currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
-	bid, errs := exchangeBidder.requestBid(context.Background(), ortbRequest, openrtb_ext.BidderAudienceNetwork, 1.0, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, true)
-	if len(errs) != 0 {
-		t.Fatalf("This should not produce errors. Got %v", errs)
-	}
-	if len(bid.bids) != 1 {
-		t.Fatalf("We should get one bid back.")
-	}
-	if bid.bids[0] == nil {
-		t.Errorf("The returned bid should not be nil.")
-	}
-}
-
-// assertEquivalentFields compares the OpenRTB request with the legacy request, using the mappings defined here:
-// https://gist.github.com/dbemiller/68aa3387189fa17d3addfb9818dd4d97
-func assertEquivalentRequests(t *testing.T, req *openrtb2.BidRequest, legacy *pbs.PBSRequest) {
-	if req.Site != nil {
-		if req.Site.Publisher.ID != legacy.AccountID {
-			t.Errorf("Account ID did not translate. OpenRTB: %s, Legacy: %s.", req.Site.Publisher.ID, legacy.AccountID)
-		}
-		if req.Site.Page != legacy.Url {
-			t.Errorf("url did not translate. OpenRTB: %v, Legacy: %v.", req.Site.Page, legacy.Url)
-		}
-		if req.Site.Domain != legacy.Domain {
-			t.Errorf("domain did not translate. OpenRTB: %v, Legacy: %v.", req.Site.Domain, legacy.Domain)
-		}
-	} else if req.App != nil {
-		if req.App.Publisher.ID != legacy.AccountID {
-			t.Errorf("Account ID did not translate. OpenRTB: %s, Legacy: %s.", req.Site.Publisher.ID, legacy.AccountID)
-		}
-	} else {
-		t.Errorf("req.site and req.app are nil. This request was invalid.")
-	}
-
-	if req.Source.TID != legacy.Tid {
-		t.Errorf("TID did not translate. OpenRTB: %s, Legacy: %s.", req.Source.TID, legacy.Tid)
-	}
-
-	expectedSecure := int8(0)
-	if req.Imp[0].Secure != nil {
-		expectedSecure = int8(*req.Imp[0].Secure)
-	}
-
-	if expectedSecure != legacy.Secure {
-		t.Errorf("tmax did not translate. OpenRTB: %d, Legacy: %d.", expectedSecure, legacy.Secure)
-	}
-	// TODO: Secure
-
-	if req.TMax != legacy.TimeoutMillis {
-		t.Errorf("tmax did not translate. OpenRTB: %d, Legacy: %d.", req.TMax, legacy.TimeoutMillis)
-	}
-
-	if req.App != legacy.App {
-		t.Errorf("app did not translate. OpenRTB: %v, Legacy: %v.", req.App, legacy.App)
-	}
-	if req.Device != legacy.Device {
-		t.Errorf("device did not translate. OpenRTB: %v, Legacy: %v.", req.Device, legacy.Device)
-	}
-	if req.User != legacy.User {
-		t.Errorf("user did not translate. OpenRTB: %v, Legacy: %v.", req.User, legacy.User)
-	}
-	if req.User != nil {
-		if id, _, _ := legacy.Cookie.GetUID("someFamily"); id != req.User.BuyerUID {
-			t.Errorf("bidder usersync did not translate. OpenRTB: %v, Legacy: %v.", req.User.BuyerUID, id)
-		}
-		if id, _, _ := legacy.Cookie.GetUID("adnxs"); id != req.User.ID {
-			t.Errorf("user ID did not translate. OpenRTB: %v, Legacy: %v.", req.User.ID, id)
-		}
-	}
-}
-
-func assertEquivalentBidder(t *testing.T, req *openrtb2.BidRequest, legacy *pbs.PBSBidder) {
-	if len(req.Imp) != len(legacy.AdUnits) {
-		t.Errorf("Wrong number of Imps. Expected %d, got %d", len(req.Imp), len(legacy.AdUnits))
-		return
-	}
-	for i := 0; i < len(req.Imp); i++ {
-		assertEquivalentImp(t, i, &req.Imp[i], &legacy.AdUnits[i])
-	}
-}
-
-func assertEquivalentImp(t *testing.T, index int, imp *openrtb2.Imp, legacy *pbs.PBSAdUnit) {
-	if imp.ID != legacy.BidID {
-		t.Errorf("imp[%d].id did not translate. OpenRTB %s, legacy %s", index, imp.ID, legacy.BidID)
-	}
-
-	if imp.Instl != legacy.Instl {
-		t.Errorf("imp[%d].instl did not translate. OpenRTB %d, legacy %d", index, imp.Instl, legacy.Instl)
-	}
-
-	if params, _, _, _ := jsonparser.Get(imp.Ext, "bidder"); !jsonpatch.Equal(params, legacy.Params) {
-		t.Errorf("imp[%d].ext.bidder did not translate. OpenRTB %s, legacy %s", index, string(params), string(legacy.Params))
-	}
-
-	if imp.Banner != nil {
-		if imp.Banner.TopFrame != legacy.TopFrame {
-			t.Errorf("imp[%d].topframe did not translate. OpenRTB %d, legacy %d", index, imp.Banner.TopFrame, legacy.TopFrame)
-		}
-		if imp.Banner.Format[0].W != legacy.Sizes[0].W {
-			t.Errorf("imp[%d].format[0].w did not translate. OpenRTB %d, legacy %d", index, imp.Banner.Format[0].W, legacy.Sizes[0].W)
-		}
-		if imp.Banner.Format[0].H != legacy.Sizes[0].H {
-			t.Errorf("imp[%d].format[0].h did not translate. OpenRTB %d, legacy %d", index, imp.Banner.Format[0].H, legacy.Sizes[0].H)
-		}
-	}
-
-	if imp.Video != nil {
-		if !reflect.DeepEqual(imp.Video.MIMEs, legacy.Video.Mimes) {
-			t.Errorf("imp[%d].video.mimes did not translate. OpenRTB %v, legacy %v", index, imp.Video.MIMEs, legacy.Video.Mimes)
-		}
-		if len(imp.Video.Protocols) != len(imp.Video.Protocols) {
-			t.Errorf("len(imp[%d].video.protocols) did not match. OpenRTB %d, legacy %d", index, len(imp.Video.Protocols), len(imp.Video.Protocols))
-			return
-		}
-		for i := 0; i < len(imp.Video.Protocols); i++ {
-			if int8(imp.Video.Protocols[i]) != legacy.Video.Protocols[i] {
-				t.Errorf("imp[%d].video.protocol[%d] did not match. OpenRTB %d, legacy %d", index, i, imp.Video.Protocols[i], imp.Video.Protocols[i])
-			}
-		}
-		if len(imp.Video.PlaybackMethod) > 0 {
-			if int8(imp.Video.PlaybackMethod[0]) != legacy.Video.PlaybackMethod {
-				t.Errorf("imp[%d].video.playbackmethod[0] did not translate. OpenRTB %d, legacy %d", index, int8(imp.Video.PlaybackMethod[0]), legacy.Video.PlaybackMethod)
-			}
-		}
-		if imp.Video.Skip == nil {
-			if legacy.Video.Skippable != 0 {
-				t.Errorf("imp[%d].video.skip did not translate. OpenRTB nil, legacy %d", index, legacy.Video.Skippable)
-			}
-		} else {
-			if int(*imp.Video.Skip) != legacy.Video.Skippable {
-				t.Errorf("imp[%d].video.skip did not translate. OpenRTB %d, legacy %d", index, *imp.Video.Skip, legacy.Video.Skippable)
-			}
-		}
-		if imp.Video.StartDelay == nil {
-			if legacy.Video.Startdelay != 0 {
-				t.Errorf("imp[%d].video.startdelay did not translate. OpenRTB nil, legacy %d", index, legacy.Video.Startdelay)
-			}
-		} else {
-			if int64(*imp.Video.StartDelay) != legacy.Video.Startdelay {
-				t.Errorf("imp[%d].video.startdelay did not translate. OpenRTB %d, legacy %d", index, int64(*imp.Video.StartDelay), legacy.Video.Startdelay)
-			}
-		}
-		if imp.Video.MaxDuration != legacy.Video.Maxduration {
-			t.Errorf("imp[%d].video.maxduration did not translate. OpenRTB %d, legacy %d", index, imp.Video.MaxDuration, legacy.Video.Maxduration)
-		}
-		if imp.Video.MinDuration != legacy.Video.Minduration {
-			t.Errorf("imp[%d].video.minduration did not translate. OpenRTB %d, legacy %d", index, imp.Video.MinDuration, legacy.Video.Minduration)
-		}
-	}
-}
-
-type mockLegacyAdapter struct {
-	returnedBids  pbs.PBSBidSlice
-	returnedError error
-	gotRequest    *pbs.PBSRequest
-	gotBidder     *pbs.PBSBidder
-}
-
-func (a *mockLegacyAdapter) Name() string {
-	return "someFamily"
-}
-
-func (a *mockLegacyAdapter) SkipNoCookies() bool {
-	return false
-}
-
-func (a *mockLegacyAdapter) GetUsersyncInfo() (*usersync.UsersyncInfo, error) {
-	return nil, nil
-}
-
-func (a *mockLegacyAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder *pbs.PBSBidder) (pbs.PBSBidSlice, error) {
-	a.gotRequest = req
-	a.gotBidder = bidder
-	return a.returnedBids, a.returnedError
-}
diff --git a/prebid_cache_client/prebid_cache_test.go b/prebid_cache_client/prebid_cache_test.go
index 2b33f2ce..65688789 100644
--- a/prebid_cache_client/prebid_cache_test.go
+++ b/prebid_cache_client/prebid_cache_test.go
@@ -82,19 +82,10 @@ func TestPrebidClient(t *testing.T) {
 	server := httptest.NewServer(http.HandlerFunc(DummyPrebidCacheServer))
 	defer server.Close()
 
-	cobj := make([]*CacheObject, 5)
+	cobj := make([]*CacheObject, 3)
 
-	// example bids from lifestreet, facebook, and appnexus
+	// example bids
 	cobj[0] = &CacheObject{
-		IsVideo: false,
-		Value: &BidCache{
-			Adm:    "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"//www.w3.org/1999/xhtml\">\n<head> \n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n<!-- Copyright (c) 2016 LifeStreet Corporation -->\n<script>\n    var ad_protocol_scheme = 'http';\n    var hypeAnimationDelayedExecute = false;\n</script>\n<script src=\"http://cdn.lfstmedia.com/~cdn/Ads/ad_shared/js/prefixfree.min.js\"></script>\n<!-- -->\n<script>\nfunction writeViewPort() {\n    var ua = navigator.userAgent;\n    var viewportChanged = false;\n    var scale = 0;\n    if (ua.indexOf(\"Android\") >= 0 && ua.indexOf(\"AppleWebKit\") >= 0) {\n        var webkitVersion = parseFloat(ua.slice(ua.indexOf(\"AppleWebKit\") + 12));\n        if (webkitVersion < 535) {\n            viewportChanged = true;\n            scale = getScaleWithScreenwidth();\n          document.write('<meta name=\"viewport\" content=\"width=320, initial-scale=' + scale + ', minimum-scale=' + scale + ', maximum-scale=' + scale + '\" />');\n        }\n    }\n\n    if (ua.indexOf(\"Firefox\") >= 0) {\n        viewportChanged = true;\n        scale = (getScaleWithScreenwidth() / 2);\n        document.write('<meta name=\"viewport\" content=\"width=320, user-scalable=false, initial-scale=' + scale + '\" />');\n    }\n\n    if (!viewportChanged) {\n        document.write('<meta name=\"viewport\" content=\"width=320, user-scalable=false\" />');\n    }\n\n    if (ua.indexOf(\"IEMobile\") >= 0) {\n        document.write('<meta name=\"MobileOptimized\" content=\"320\" />');\n    }\n\n    document.write('<meta name=\"HandheldFriendly\" content=\"true\"/>');\n}\n\nfunction getScaleWithScreenwidth() {\n    var viewportWidth = 320;\n    var screenWidth = window.screen.width / window.devicePixelRatio;\n    return (screenWidth / viewportWidth);\n}\nwriteViewPort();\n</script>\n\n<!-- -->\n<script src='http://cdn.lfstmedia.com/~cdn/Ads/ad_shared/js/scale.min.js'></script><!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<style>\n/*  */\n    #lsm_mobile_ad.animation_stopped *, .animation_stopped #container * {\n        -webkit-animation: none !important;\n        animation: none !important;\n    }\n    #AnimationFailover { display:none;}\n    .animation_stopped #AnimationFailover { display:block;}\n    body {padding:0; margin:0;-webkit-transform: translateZ(0px);line-height:1.2;}\n    /*  */\n    img{border:0px;}\n    a{text-decoration:none; cursor:pointer; color:#1F768C; z-index: 1;}\n    a:hover, a:hover *{text-decoration:underline;}\n    a.nounderline:hover{text-decoration:none;}\n    .hidden{display:none;}\n    .show{display:block;}\n    \n    #lsm_overlay {left: 0;top: 0;margin: 0;padding: 0;overflow: hidden;}\n    #lsm_overlay_inner {position: absolute;left: 0;top: 0;margin: 0;padding: 0;overflow: hidden;width:320px;height:480px;}\n    /*          */\n        .mp_center {position:static;top:initial;left:initial;margin-left:0px !important;margin-top:0px !important;}        /*  */\n    /*  */\n    #container {position: relative;left: 0;top: 0;margin: 0;padding: 0;width: 320px;height: 480px; background:#FFFFFF; color:#000; font-size:12px; font-family:Arial, Helvetica, sans-serif;z-index:1;text-align:left;}\n    #animation_blocks * {-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);}\n    #click_overlay{width:320px; height:480px; position:absolute; top: 0px; left: 0px; z-index:9999; display: block;}\n    \n    .text, .logo_extra, .image{position:absolute; float:left;}\n    .image a {display:inline-block;}\n    \n    /*  */\n    \n    /*  */\n    \n    /*  */\n    \n    /*  */\n    \n    /*  */\n    a.hide {\n        visibility:hidden !important;\n    }\n    a.Text1, a.Text2, a.Text3, a.Text4, a.Text5 {\n        visibility:visible !important;\n    }\n    a.hideText1, a.hideText2, a.hideText3, a.hideText4, a.hideText5 {\n        display:none !important;\n    }\n    \n    /*  */\n    \n    /* CSS3 Animations */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n      \n/*  */\n\n/*  */\n</style>\n<!--  -->\n\n<!--  -->\n<!--  -->\n</head>\n\n<body id=\"lsm_mobile_ad\">\n<!-- MoPub RTB cut here BEGIN -->\n<img src=\"http://md-nj.lfstmedia.com/track/1002?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&__adt=5606652576928142935&__ade=2&__stamp=1506349598367\" width=\"0\" height=\"0\" style=\"position:absolute; visibility:hidden\" />\n<!-- Close Button Underlay\n     -->\n<div id=\"lsm_overlay\">\n<div id=\"lsm_overlay_inner\">\n<!--  -->\n<div id=\"container\">\n<div id=\"animation_blocks\">\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n</div>\n<!-- -->\n    <a id=\"click_overlay\" target=\"_blank\" href=\"http://md-nj.lfstmedia.com/click/cmp6178/5606652576928142935/2?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&adkey=6f5&_ifa=87ECBA49-908A-428F-9DE7-4B9CED4F486C&_ifamd5=06410baf3501ce3936fbef4c2109cfe6&_ifasha1=1a4ffaf85f3240f9e9f24e7d99c30ec8e38102b5&slot=slot178682&__stamp=1506349598366&ad=crv65774&_cx=$$CX$$&_cy=$$CY$$&_celt=$$ELT-ID$$&redirectURL=\"></a>\n<!--  -->\n<!--  -->\n<!-- Background Elemets -->\n\n<!--  -->\n<!--  -->\n\n<!-- IMAGE -->\n\n<!--  -->\n    <div class=\"image\" style=\"top:0px;left:0px;z-index:1;display:block;width:320px;text-align:left;\">\n        <a id=\"Image1\" href=\"javascript:;\" target=\"_blank\" class=\"Image1_universal\">\n            <img src=\"http://cdn.lfstmedia.com/~cdn/Ads/1b2bd280-d280-1b2b-99d4-6eb6c97ec732.png\" style=\"height:480px;width:320px;\" border=\"0\" />\n        </a>\n    </div>\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n     \n<!-- TEXT -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!-- Border\n     -->\n<script type=\"text/javascript\" src=\"https://cdn.lfstmedia.com/~cdn/JS/02/tracking-1.0.js\"></script>\n<script type=\"text/javascript\">\n    var tracking = lsm.Tracking.getInstance();\n    tracking.setConfiguration([\n        {\n            'type': 'open_link',\n            'pixels': []\n        }\n    ]);\n    tracking.addClickEventListener();\n</script>\n</div>\n</div>\n</div>\n<!--\n-->\n<!--  -->\n<!-- -->\n<script type=\"text/javascript\">\n    var scale_ua = navigator.userAgent;\n    if (scale_ua.indexOf(\"Android\") != -1) {\n        document.getElementById(\"lsm_overlay\").style.position = \"static\";\n    }\n    scaleAd(320, 480);\n</script>\n<!-- -->\n\n<!--  -->\n<script>\n</script>\n<!--  -->\n<script>\n    var clickOverlay = document.getElementById(\"click_overlay\");\n    function disableClickOverlay() {\n        clickOverlay.style.zIndex = '0';\n    }\n    function enableClickOverlay() {\n        setTimeout(function(){ clickOverlay.style.zIndex = '9999';}, 500);\n    }  \n</script>\n\n<!--MRC Accredited Traffic Measurement-->\n<!-- Heatmap Pixel -->\n<script type=\"text/javascript\" src=\"http://md-nj.lfstmedia.com/~cdn/JS/02/hm.js\"></script>\n<img height=\"0\" width=\"0\" style=\"border-style:none;\" alt=\"\" src=\"http://md-nj.lfstmedia.com/syspixel?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&__adt=5606652576928142935&__ade=2&type=tracking&rqc=0w23qR-q7O43weAFbbpzD-gxdTCKySMe-Ef74TByOeGfsOXY0_QKnpwzqvXgrzPZOLZfI__68S9kCKELawQtZcO6kMyvlPM55uCaRZWng_j5btuPaEuXyA&pab=true&__stamp=1506349598367\"/>\n<img height=\"0\" width=\"0\" style=\"border-style:none;\" alt=\"\" src=\"http://md-nj.lfstmedia.com/track/60?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&__adt=5606652576928142935&__ade=2&__stamp=1506349598367\"/>\n</body>\n</html>",
-			NURL:   "http://test.com/syspixel?__ads=ip8070-3PJ4q4QyZxnHE6woGe1sQ3&__adt=4122105428549383603&__ade=2&type=tracking&rqc=0w23qR-q7O7MsGkWlR9wOBm8qL7msKBtSKRJV3Pw0a0tZ47xJTnT2JwzqvXgrzPZOLZfI__68S9kCKELawQtZcO6kMyvlPM55uCaRZWng_j5btuPaEuXyA&pab=true",
-			Width:  300,
-			Height: 250,
-		},
-	}
-	cobj[1] = &CacheObject{
 		IsVideo: false,
 		Value: &BidCache{
 			Adm:    "{\"type\":\"ID\",\"bid_id\":\"8255649814109237089\",\"placement_id\":\"1995257847363113_1997038003851764\",\"resolved_placement_id\":\"1995257847363113_1997038003851764\",\"sdk_version\":\"4.25.0-appnexus.bidding\",\"device_id\":\"87ECBA49-908A-428F-9DE7-4B9CED4F486C\",\"template\":7,\"payload\":\"null\"}",
@@ -103,7 +94,7 @@ func TestPrebidClient(t *testing.T) {
 			Height: 250,
 		},
 	}
-	cobj[2] = &CacheObject{
+	cobj[1] = &CacheObject{
 		IsVideo: false,
 		Value: &BidCache{
 			Adm:    "<script type=\"application/javascript\" src=\"http://nym1-ib.adnxs.com/ab?e=wqT_3QLVBqBVAwAAAwDWAAUBCN_rpM4FEIziq9qV-8avPRiq8Nq0r-ek-wcqLQkAAAECCOA_EQEHNAAA4D8ZAAAAQOF6hD8hERIAKREJoDCV4t0EOL4HQL4HSAJQy5aGI1it2kRgAGiRQHj14AOAAQCKAQNVU0SSBQbwUpgBrAKgAfoBqAEBsAEAuAECwAEDyAEC0AEC2AEA4AEA8AEAigI7dWYoJ2EnLCAxMzk5NzAwLCAxNTA2MzU4NzUxKTt1ZigncicsIDczNTAxNTE1Nh4A8I2SAu0BIXREUGp6d2llLTVJSEVNdVdoaU1ZQUNDdDJrUXdBRGdBUUFSSXZnZFFsZUxkQkZnQVlOSUdhQUJ3WEhqU0E0QUJYSWdCMGdPUUFRR1lBUUdnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmtzSzlsZXQwMGpfWkFRQUFBAQMkUEFfNEFFQTlRRQEOLEFtQUlBb0FJQXRRSQUQAHYNCIh3QUlBeUFJQTRBSUE2QUlBLUFJQWdBTUVrQU1BbUFNQnFBTwXQaHVnTUpUbGxOTWpveU9USXmaAi0hOWdoQW5naQUgAEUN8ChyZHBFSUFRb0FEbzIwAFjYAugH4ALH0wHyAhEKBkFEVl9JRBIHMSlqBRQIQ1BHBRQYMzU0NjYyNwEUCAVDUAET9BUBCDE0OTkwNzUwgAMBiAMBkAMAmAMUoAMBqgMAwAOsAsgDANIDKAgAEiQ0NzJhYjY4MS03MDUxLTQzMjktOTc5MS1hZTI4YTg4ZWJmNmLYAwDgAwDoAwL4AwCABACSBAkvb3BlbnJ0YjKYBACoBLj7A7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIECU5ZTTI6MjkyMtoEAggB4AQA8ATLloYjggUZQXBwTmV4dXMuUHJlYmlkTW9iaWxlRGVtb4gFAZgFAKAF____________AaoFJERDMzVGRjlGLTA0RjUtNDBFQi1CRDJFLTA1MzY5QjVCOUMxNsAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQA.&s=49790274de0e076a2b8b9577c2cce27ff3919239&pp=${AUCTION_PRICE}&\"></script>",
@@ -111,14 +102,10 @@ func TestPrebidClient(t *testing.T) {
 			Height: 250,
 		},
 	}
-	cobj[3] = &CacheObject{
+	cobj[2] = &CacheObject{
 		IsVideo: true,
 		Value:   "<script type=\"application/javascript\" src=\"http://nym1-ib.adnxs.com/ab?e=wqT_3QLVBqBVAwAAAwDWAAUBCN_rpM4FEIziq9qV-8avPRiq8Nq0r-ek-wcqLQkAAAECCOA_EQEHNAAA4D8ZAAAAQOF6hD8hERIAKREJoDCV4t0EOL4HQL4HSAJQy5aGI1it2kRgAGiRQHj14AOAAQCKAQNVU0SSBQbwUpgBrAKgAfoBqAEBsAEAuAECwAEDyAEC0AEC2AEA4AEA8AEAigI7dWYoJ2EnLCAxMzk5NzAwLCAxNTA2MzU4NzUxKTt1ZigncicsIDczNTAxNTE1Nh4A8I2SAu0BIXREUGp6d2llLTVJSEVNdVdoaU1ZQUNDdDJrUXdBRGdBUUFSSXZnZFFsZUxkQkZnQVlOSUdhQUJ3WEhqU0E0QUJYSWdCMGdPUUFRR1lBUUdnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmtzSzlsZXQwMGpfWkFRQUFBAQMkUEFfNEFFQTlRRQEOLEFtQUlBb0FJQXRRSQUQAHYNCIh3QUlBeUFJQTRBSUE2QUlBLUFJQWdBTUVrQU1BbUFNQnFBTwXQaHVnTUpUbGxOTWpveU9USXmaAi0hOWdoQW5naQUgAEUN8ChyZHBFSUFRb0FEbzIwAFjYAugH4ALH0wHyAhEKBkFEVl9JRBIHMSlqBRQIQ1BHBRQYMzU0NjYyNwEUCAVDUAET9BUBCDE0OTkwNzUwgAMBiAMBkAMAmAMUoAMBqgMAwAOsAsgDANIDKAgAEiQ0NzJhYjY4MS03MDUxLTQzMjktOTc5MS1hZTI4YTg4ZWJmNmLYAwDgAwDoAwL4AwCABACSBAkvb3BlbnJ0YjKYBACoBLj7A7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIECU5ZTTI6MjkyMtoEAggB4AQA8ATLloYjggUZQXBwTmV4dXMuUHJlYmlkTW9iaWxlRGVtb4gFAZgFAKAF____________AaoFJERDMzVGRjlGLTA0RjUtNDBFQi1CRDJFLTA1MzY5QjVCOUMxNsAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQA.&s=49790274de0e076a2b8b9577c2cce27ff3919239&pp=${AUCTION_PRICE}&\"></script>",
 	}
-	cobj[4] = &CacheObject{
-		IsVideo: true,
-		Value:   "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"//www.w3.org/1999/xhtml\">\n<head> \n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n<!-- Copyright (c) 2016 LifeStreet Corporation -->\n<script>\n    var ad_protocol_scheme = 'http';\n    var hypeAnimationDelayedExecute = false;\n</script>\n<script src=\"http://cdn.lfstmedia.com/~cdn/Ads/ad_shared/js/prefixfree.min.js\"></script>\n<!-- -->\n<script>\nfunction writeViewPort() {\n    var ua = navigator.userAgent;\n    var viewportChanged = false;\n    var scale = 0;\n    if (ua.indexOf(\"Android\") >= 0 && ua.indexOf(\"AppleWebKit\") >= 0) {\n        var webkitVersion = parseFloat(ua.slice(ua.indexOf(\"AppleWebKit\") + 12));\n        if (webkitVersion < 535) {\n            viewportChanged = true;\n            scale = getScaleWithScreenwidth();\n          document.write('<meta name=\"viewport\" content=\"width=320, initial-scale=' + scale + ', minimum-scale=' + scale + ', maximum-scale=' + scale + '\" />');\n        }\n    }\n\n    if (ua.indexOf(\"Firefox\") >= 0) {\n        viewportChanged = true;\n        scale = (getScaleWithScreenwidth() / 2);\n        document.write('<meta name=\"viewport\" content=\"width=320, user-scalable=false, initial-scale=' + scale + '\" />');\n    }\n\n    if (!viewportChanged) {\n        document.write('<meta name=\"viewport\" content=\"width=320, user-scalable=false\" />');\n    }\n\n    if (ua.indexOf(\"IEMobile\") >= 0) {\n        document.write('<meta name=\"MobileOptimized\" content=\"320\" />');\n    }\n\n    document.write('<meta name=\"HandheldFriendly\" content=\"true\"/>');\n}\n\nfunction getScaleWithScreenwidth() {\n    var viewportWidth = 320;\n    var screenWidth = window.screen.width / window.devicePixelRatio;\n    return (screenWidth / viewportWidth);\n}\nwriteViewPort();\n</script>\n\n<!-- -->\n<script src='http://cdn.lfstmedia.com/~cdn/Ads/ad_shared/js/scale.min.js'></script><!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<style>\n/*  */\n    #lsm_mobile_ad.animation_stopped *, .animation_stopped #container * {\n        -webkit-animation: none !important;\n        animation: none !important;\n    }\n    #AnimationFailover { display:none;}\n    .animation_stopped #AnimationFailover { display:block;}\n    body {padding:0; margin:0;-webkit-transform: translateZ(0px);line-height:1.2;}\n    /*  */\n    img{border:0px;}\n    a{text-decoration:none; cursor:pointer; color:#1F768C; z-index: 1;}\n    a:hover, a:hover *{text-decoration:underline;}\n    a.nounderline:hover{text-decoration:none;}\n    .hidden{display:none;}\n    .show{display:block;}\n    \n    #lsm_overlay {left: 0;top: 0;margin: 0;padding: 0;overflow: hidden;}\n    #lsm_overlay_inner {position: absolute;left: 0;top: 0;margin: 0;padding: 0;overflow: hidden;width:320px;height:480px;}\n    /*          */\n        .mp_center {position:static;top:initial;left:initial;margin-left:0px !important;margin-top:0px !important;}        /*  */\n    /*  */\n    #container {position: relative;left: 0;top: 0;margin: 0;padding: 0;width: 320px;height: 480px; background:#FFFFFF; color:#000; font-size:12px; font-family:Arial, Helvetica, sans-serif;z-index:1;text-align:left;}\n    #animation_blocks * {-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);}\n    #click_overlay{width:320px; height:480px; position:absolute; top: 0px; left: 0px; z-index:9999; display: block;}\n    \n    .text, .logo_extra, .image{position:absolute; float:left;}\n    .image a {display:inline-block;}\n    \n    /*  */\n    \n    /*  */\n    \n    /*  */\n    \n    /*  */\n    \n    /*  */\n    a.hide {\n        visibility:hidden !important;\n    }\n    a.Text1, a.Text2, a.Text3, a.Text4, a.Text5 {\n        visibility:visible !important;\n    }\n    a.hideText1, a.hideText2, a.hideText3, a.hideText4, a.hideText5 {\n        display:none !important;\n    }\n    \n    /*  */\n    \n    /* CSS3 Animations */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n\n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n    /*  */\n    \n    /*      */\n    \n      \n/*  */\n\n/*  */\n</style>\n<!--  -->\n\n<!--  -->\n<!--  -->\n</head>\n\n<body id=\"lsm_mobile_ad\">\n<!-- MoPub RTB cut here BEGIN -->\n<img src=\"http://md-nj.lfstmedia.com/track/1002?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&__adt=5606652576928142935&__ade=2&__stamp=1506349598367\" width=\"0\" height=\"0\" style=\"position:absolute; visibility:hidden\" />\n<!-- Close Button Underlay\n     -->\n<div id=\"lsm_overlay\">\n<div id=\"lsm_overlay_inner\">\n<!--  -->\n<div id=\"container\">\n<div id=\"animation_blocks\">\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n</div>\n<!-- -->\n    <a id=\"click_overlay\" target=\"_blank\" href=\"http://md-nj.lfstmedia.com/click/cmp6178/5606652576928142935/2?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&adkey=6f5&_ifa=87ECBA49-908A-428F-9DE7-4B9CED4F486C&_ifamd5=06410baf3501ce3936fbef4c2109cfe6&_ifasha1=1a4ffaf85f3240f9e9f24e7d99c30ec8e38102b5&slot=slot178682&__stamp=1506349598366&ad=crv65774&_cx=$$CX$$&_cy=$$CY$$&_celt=$$ELT-ID$$&redirectURL=\"></a>\n<!--  -->\n<!--  -->\n<!-- Background Elemets -->\n\n<!--  -->\n<!--  -->\n\n<!-- IMAGE -->\n\n<!--  -->\n    <div class=\"image\" style=\"top:0px;left:0px;z-index:1;display:block;width:320px;text-align:left;\">\n        <a id=\"Image1\" href=\"javascript:;\" target=\"_blank\" class=\"Image1_universal\">\n            <img src=\"http://cdn.lfstmedia.com/~cdn/Ads/1b2bd280-d280-1b2b-99d4-6eb6c97ec732.png\" style=\"height:480px;width:320px;\" border=\"0\" />\n        </a>\n    </div>\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n     \n<!-- TEXT -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!--  -->\n<!-- Border\n     -->\n<script type=\"text/javascript\" src=\"https://cdn.lfstmedia.com/~cdn/JS/02/tracking-1.0.js\"></script>\n<script type=\"text/javascript\">\n    var tracking = lsm.Tracking.getInstance();\n    tracking.setConfiguration([\n        {\n            'type': 'open_link',\n            'pixels': []\n        }\n    ]);\n    tracking.addClickEventListener();\n</script>\n</div>\n</div>\n</div>\n<!--\n-->\n<!--  -->\n<!-- -->\n<script type=\"text/javascript\">\n    var scale_ua = navigator.userAgent;\n    if (scale_ua.indexOf(\"Android\") != -1) {\n        document.getElementById(\"lsm_overlay\").style.position = \"static\";\n    }\n    scaleAd(320, 480);\n</script>\n<!-- -->\n\n<!--  -->\n<script>\n</script>\n<!--  -->\n<script>\n    var clickOverlay = document.getElementById(\"click_overlay\");\n    function disableClickOverlay() {\n        clickOverlay.style.zIndex = '0';\n    }\n    function enableClickOverlay() {\n        setTimeout(function(){ clickOverlay.style.zIndex = '9999';}, 500);\n    }  \n</script>\n\n<!--MRC Accredited Traffic Measurement-->\n<!-- Heatmap Pixel -->\n<script type=\"text/javascript\" src=\"http://md-nj.lfstmedia.com/~cdn/JS/02/hm.js\"></script>\n<img height=\"0\" width=\"0\" style=\"border-style:none;\" alt=\"\" src=\"http://md-nj.lfstmedia.com/syspixel?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&__adt=5606652576928142935&__ade=2&type=tracking&rqc=0w23qR-q7O43weAFbbpzD-gxdTCKySMe-Ef74TByOeGfsOXY0_QKnpwzqvXgrzPZOLZfI__68S9kCKELawQtZcO6kMyvlPM55uCaRZWng_j5btuPaEuXyA&pab=true&__stamp=1506349598367\"/>\n<img height=\"0\" width=\"0\" style=\"border-style:none;\" alt=\"\" src=\"http://md-nj.lfstmedia.com/track/60?__ads=ip8070-qXer7PudnkSfL6VObUy8Aq&__adt=5606652576928142935&__ade=2&__stamp=1506349598367\"/>\n</body>\n</html>",
-	}
 	InitPrebidCache(server.URL)
 
 	ctx := context.TODO()
@@ -136,12 +123,6 @@ func TestPrebidClient(t *testing.T) {
 	if cobj[2].UUID != "UUID-3" {
 		t.Errorf("Third object UUID was '%s', should have been 'UUID-3'", cobj[2].UUID)
 	}
-	if cobj[3].UUID != "UUID-4" {
-		t.Errorf("Fourth object UUID was '%s', should have been 'UUID-4'", cobj[3].UUID)
-	}
-	if cobj[4].UUID != "UUID-5" {
-		t.Errorf("Fifth object UUID was '%s', should have been 'UUID-5'", cobj[4].UUID)
-	}
 
 	delay = 5 * time.Millisecond
 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)
diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go
index 10aaafd5..2ebd541d 100644
--- a/usersync/usersyncers/syncer_test.go
+++ b/usersync/usersyncers/syncer_test.go
@@ -51,6 +51,7 @@ func TestNewSyncerMap(t *testing.T) {
 			string(openrtb_ext.BidderEmxDigital):       syncConfig,
 			string(openrtb_ext.BidderEngageBDR):        syncConfig,
 			string(openrtb_ext.BidderEPlanning):        syncConfig,
+			string(openrtb_ext.BidderEVolution):        syncConfig,
 			string(openrtb_ext.BidderGamma):            syncConfig,
 			string(openrtb_ext.BidderGamoshi):          syncConfig,
 			string(openrtb_ext.BidderGrid):             syncConfig,
@@ -60,7 +61,6 @@ func TestNewSyncerMap(t *testing.T) {
 			string(openrtb_ext.BidderIx):               syncConfig,
 			string(openrtb_ext.BidderJixie):            syncConfig,
 			string(openrtb_ext.BidderKrushmedia):       syncConfig,
-			string(openrtb_ext.BidderLifestreet):       syncConfig,
 			string(openrtb_ext.BidderLockerDome):       syncConfig,
 			string(openrtb_ext.BidderLogicad):          syncConfig,
 			string(openrtb_ext.BidderLunaMedia):        syncConfig,