Repository: prebid/prebid-server
Pull request #1869 (2021-05-27 15:45:38)

Criteo: accept zoneId and networkId alternate case
Our PBS adapter has been released initially accepting both **zoneid** and **networkid** (with that specific case).
However, our public Prebid documentation states that we are accepting **zoneId** and **networkId**, causing issues for publishers using both adapters.

So, we want our PBS adapter to accept both cases.

SyntaxNode: This looks god technically. I have a concern over publisher confusion before we merge this in. There are some hosts who build a user interface on top of this information and publishers might be confused on which field to choose especially if they don't notice the capitalization difference. Do you prefer one style over another?
leonardlabat: Well the one zoneId / networkId is cleary the prefered one (that's the one authored in the Prebid website documentation).
SyntaxNode: > Well the one zoneId / networkId is cleary the prefered one (that's the one authored in the Prebid website documentation).

Gotcha. Thank you for clarifying. I don't believe there's a way in json schema to specify which one is preferred. To let publishers know and to give a hint to automated systems, are you willing to include the word "preferred" in the description of the lower case ones? Something like:

"Impression's zone ID., preferred",
"Impression's zone ID (preferred).",
leonardlabat: I've pushed an update @SyntaxNode thanks for the suggestion !

Do you think it'll be possible to have this included in the next release of prebid server please ? we have a couple of publishers waiting for that change

Thanks

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/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,