function securityTokenHandler0(sServiceUrl) {
			assert.strictEqual(sServiceUrl, sTeaBusi);
			return undefined; // not responsible
		}
******************************************************************************************
	// Scenario: requestSideEffects refreshes properties at the parent entity with the help of path
	// reduction via partner attributes. See that bubbling up is necessary again when processing the
	// reduced path in the parent context.
	// JIRA: CPOUI5ODATAV4-103
	// Extended with a collection-valued structural property and a collection-valued navigation
	// property.
	// JIRA: CPOUI5ODATAV4-221
	// For a context of a list binding, both a refresh of the whole collection and changes to
	// structural properties only ({"$PropertyPath":"*"}) are requested at the same time. Also, both
	// a refresh of the whole collection and of a single item ({$NavigationPropertyPath : ""}) are
	// requested at the same time. No duplicate requests are invoked, no errors happen.
	// BCP: 2070206648
	QUnit.test("requestSideEffects: path reduction", function (assert) {
		var oContext,
			oModel = this.createSalesOrdersModel({autoExpandSelect : true}),
			sView = '\
<FlexBox binding="{path : \'/SalesOrderList(\\\'42\\\')\', parameters : {$select : \'Messages\'}}">\
	<FlexBox binding="{}">\
		<Text id="note" text="{Note}"/>\
		<Table id="items" items="{path : \'SO_2_SOITEM\', parameters : {$$ownRequest : true}}">\
			<Text id="position" text="{ItemPosition}"/>\
			<Text id="amount" text="{GrossAmount}"/>\
		</Table>\
		<Table id="schedules" items="{path : \'SO_2_SCHDL\', parameters : {$$ownRequest : true}}">\
			<Text id="key" text="{ScheduleKey}"/>\
		</Table>\
	</FlexBox>\
</FlexBox>',
			that = this;

		this.expectRequest("SalesOrderList('42')?$select=Messages,Note,SalesOrderID", {
				Note : "Note",
				SalesOrderID : "42"
			})
			.expectChange("note", "Note")
			.expectRequest("SalesOrderList('42')/SO_2_SOITEM?$select=GrossAmount,ItemPosition"
				+ ",SalesOrderID&$skip=0&$top=100", {
				value : [
					{GrossAmount : "3.14", ItemPosition : "0010", SalesOrderID : "42"},
					{GrossAmount : "2.72", ItemPosition : "0020", SalesOrderID : "42"}
				]
			})
			.expectChange("position", ["0010", "0020"])
			.expectChange("amount", ["3.14", "2.72"])
			.expectRequest("SalesOrderList('42')/SO_2_SCHDL?$select=ScheduleKey&$skip=0&$top=100",
				{value : [{ScheduleKey : "A"}]})
			.expectChange("key", ["A"]);

		return this.createView(assert, sView, oModel).then(function () {
			oContext = that.oView.byId("items").getItems()[0].getBindingContext();

			that.expectRequest("SalesOrderList('42')?$select=Messages,Note",
					{Note : "refreshed Note"})
				.expectRequest("SalesOrderList('42')"
					+ "/SO_2_SOITEM(SalesOrderID='42',ItemPosition='0010')?$select=GrossAmount", {
					GrossAmount : "1.41"
				})
				.expectRequest("SalesOrderList('42')/SO_2_SCHDL?$select=ScheduleKey"
					+ "&$skip=0&$top=100", {value : [{ScheduleKey : "B"}]})
				.expectChange("note", "refreshed Note")
				.expectChange("amount", ["1.41"])
				.expectChange("key", ["B"]);

			return Promise.all([
				// code under test
				oContext.requestSideEffects([
					{$PropertyPath : "GrossAmount"},
					{$PropertyPath : "SOITEM_2_SO/Messages"},
					{$PropertyPath : "SOITEM_2_SO/Note"},
					{$NavigationPropertyPath : "SOITEM_2_SO/SO_2_SCHDL"}
				]),
				that.waitForChanges(assert)
			]);
		}).then(function () {
			that.expectRequest("SalesOrderList('42')/SO_2_SOITEM?$select=GrossAmount,ItemPosition"
					+ ",SalesOrderID&$skip=0&$top=100", {
					value : [
						{GrossAmount : "10.42", ItemPosition : "0010", SalesOrderID : "42"},
						{GrossAmount : "30.42", ItemPosition : "0030", SalesOrderID : "42"}
					]
				})
				.expectChange("position", [, "0030"])
				.expectChange("amount", ["10.42", "30.42"]);

			return Promise.all([
				// code under test
				oContext.requestSideEffects([
					{$PropertyPath : "*"}, // must not lead to failure (original BCP issue)
					{$NavigationPropertyPath : "SOITEM_2_SO/SO_2_SOITEM"}
				]),
				that.waitForChanges(assert)
			]);
		}).then(function () {
			that.expectRequest("SalesOrderList('42')/SO_2_SOITEM?$select=GrossAmount,ItemPosition"
					+ ",SalesOrderID&$skip=0&$top=100", {
					value : [
						{GrossAmount : "110.42", ItemPosition : "0010", SalesOrderID : "42"},
						{GrossAmount : "130.42", ItemPosition : "0030", SalesOrderID : "42"},
						{GrossAmount : "140.42", ItemPosition : "0040", SalesOrderID : "42"}
					]
				})
				.expectChange("position", [,, "0040"])
				.expectChange("amount", ["110.42", "130.42", "140.42"]);

			return Promise.all([
				// code under test
				oContext.requestSideEffects([
					{$NavigationPropertyPath : ""}, // should not invoke a duplicate request
					{$NavigationPropertyPath : "SOITEM_2_SO/SO_2_SOITEM"}
				]),
				that.waitForChanges(assert)
			]);
		});
	});

	//*********************************************************************************************
	// Scenario: Use requestSideEffects to refresh the property AValue in a parent cache of a list
	// binding using a different API group ID. The table has a reference to this property via
	// partner attributes. Due to the group ID mismatch, it cannot reuse the value, but has to
	// request it again.
	// Ensure that requestSideEffects refreshes both copies. (This proves that we must reduce
	// collection-valued properties anywhere in the path. It also proves that we must refresh
	// partially reduced paths: "/As(1)/AValue" and "/As(1)/AtoCs(2)/CtoA/AValue" from the original
	// "/As(1)/AtoCs(2)/CtoD/DtoC/CtoA/AValue".
	// JIRA: CPOUI5ODATAV4-221
	QUnit.test("requestSideEffects: parent cache of a list binding", function (assert) {
		var oModel = this.createSpecialCasesModel({
				autoExpandSelect : true,
				updateGroupId : "update1"
			}),
			sView = '\
<FlexBox binding="{/As(1)}">\
	<Text id="avalue::form" text="{AValue}"/>\
	<Table id="table" items="{path : \'AtoCs\', parameters : {$$updateGroupId : \'update2\'}}">\
		<Text id="cid" text="{CID}"/>\
		<Text id="avalue::table" text="{CtoA/AValue}"/>\
	</Table>\
</FlexBox>\
<FlexBox id="form" binding="{CtoD}">\
	<Text text="{DID}"/>\
	<Text id="dvalue" text="{DValue}"/>\
</FlexBox>',
			that = this;

		this.expectRequest("As(1)?$select=AID,AValue", {
				AID : 1,
				AValue : 11
			})
			.expectChange("avalue::form", "11")
			.expectRequest("As(1)/AtoCs?$select=CID&$expand=CtoA($select=AID,AValue)"
				+ "&$skip=0&$top=100", {
				value : [{
					CID : 2,
					CtoA : {
						AID : 1,
						AValue : 11
					},
					CValue : 21
				}]
			})
			.expectChange("avalue::table", ["11"])
			.expectChange("cid", ["2"])
			.expectChange("dvalue");

		return this.createView(assert, sView, oModel).then(function () {
			// combined late property requests
			// see that DID does not occur twice in $Select when requested late
			that.expectRequest("As(1)/AtoCs(2)?$select=CtoD&$expand=CtoD($select=DID,DValue)", {
					CtoD : {
						DID : 3,
						DValue : 103
					}
				})
				.expectChange("dvalue", "103");

			that.oView.byId("form").setBindingContext(
				that.oView.byId("table").getItems()[0].getBindingContext());

			return that.waitForChanges(assert);
		}).then(function () {
			that.expectRequest("As(1)?$select=AValue",
					{AValue : 121}) // unrealistic, but shows the link between response and control
				.expectChange("avalue::form", "121")
				.expectRequest("As(1)/AtoCs(2)?$select=CtoA&$expand=CtoA($select=AID,AValue)", {
					CtoA : {
						AID : 1,
						AValue : 122 // unrealistic, see above
					}
				})
				.expectChange("avalue::table", ["122"]);

			// code under test
			return Promise.all([
				that.oView.byId("form").getBindingContext()
					.requestSideEffects([{$PropertyPath : "DtoC/CtoA/AValue"}], "$auto"),
				that.waitForChanges(assert)
			]);
		});
	});

	//*********************************************************************************************
	// Scenario: requestSideEffects is called at a binding w/o cache and has to delegate to a
	// context of the parent binding. Additionally it requests a property from this parent binding
	// with the help of path reduction via partner attributes. See that only one request is
	// necessary.
	// JIRA: CPOUI5ODATAV4-103
	QUnit.test("requestSideEffects: path reduction and bubble up", function (assert) {
		var oModel = this.createSpecialCasesModel({autoExpandSelect : true}),
			sView = '\
<FlexBox binding="{/As(1)}">\
	<Text id="aValue" text="{AValue}"/>\
	<FlexBox id="bInstance" binding="{AtoB}">\
		<Text id="bValue" text="{BValue}"/>\
	</FlexBox>\
</FlexBox>',
			that = this;

		this.expectRequest("As(1)?$select=AID,AValue&$expand=AtoB($select=BID,BValue)", {
				AID : 1,
				AValue : 11,
				AtoB : {
					BID : 2,
					BValue : 12
				}
			})
			.expectChange("aValue", "11")
			.expectChange("bValue", "12");

		return this.createView(assert, sView, oModel).then(function () {
			var oContext = that.oView.byId("bInstance").getElementBinding().getBoundContext();

			that.expectRequest("As(1)?$select=AValue&$expand=AtoB($select=BID,BValue)", {
					AValue : 111,
					AtoB : {
						BID : 2,
						BValue : 112
					}
				})
				.expectChange("aValue", "111")
				.expectChange("bValue", "112");

			return Promise.all([
				// code under test
				oContext.requestSideEffects(["BtoA/AValue", "BValue"]),
				that.waitForChanges(assert)
			]);
		});
	});

	//*********************************************************************************************
	// Scenario: Refresh a context binding w/o property bindings invoking a request. Ensure that
	// dependent bindings refresh and that the promise resolves.
	// JIRA: CPOUI5ODATAV4-293
	QUnit.test("ODCB: requestRefresh w/o own request", function (assert) {
		var oModel = this.createSalesOrdersModel({autoExpandSelect : true}),
			sView = '\
<FlexBox id="form" binding="{/BusinessPartnerList(\'42\')}">\
	<Table id="table" items="{path : \'BP_2_SO\', parameters : {$$ownRequest : true}}">\
		<Text id="note" text="{Note}" />\
	</Table>\
</FlexBox>',
			that = this;

		this.expectRequest("BusinessPartnerList('42')/BP_2_SO?$select=Note,SalesOrderID"
				+ "&$skip=0&$top=100", {
				value : [{
					Note : "Test",
					SalesOrderID : "0500000001"
				}]
			})
			.expectChange("note", ["Test"]);

		return this.createView(assert, sView, oModel).then(function () {
			that.expectRequest("BusinessPartnerList('42')/BP_2_SO?$select=Note,SalesOrderID"
					+ "&$skip=0&$top=100", {
					value : [{
						Note : "Test - updated",
						SalesOrderID : "0500000001"
					}]
				})
				.expectChange("note", ["Test - updated"]);

			return Promise.all([
				that.oView.byId("form").getBindingContext().requestRefresh(),
				that.waitForChanges(assert)
			]);
		});
	});

	//*********************************************************************************************
	// Scenario: hasPendingChanges and resetChanges work even while late child bindings are trying
	// to reuse the parent binding's cache.
	// JIRA: CPOUI5UISERVICESV3-1981, CPOUI5UISERVICESV3-1994
	//
	// Additionally, observe the "propertyChange" event and cancellation of its promise
	// JIRA: CPOUI5ODATAV4-1919
	QUnit.test("hasPendingChanges + resetChanges work for late child bindings", function (assert) {
		var oModel = this.createSalesOrdersModel({autoExpandSelect : true}),
			oPromise,
			sView = '\
<Table id="orders" items="{path : \'/SalesOrderList\', parameters : {\
		$expand : {\
			SO_2_SOITEM : {\
				$select : [\'ItemPosition\', \'Note\', \'SalesOrderID\']\
			}\
		},\
		$select : \'Note\'\
	}}">\
	<Input id="note" value="{Note}"/>\
</Table>\
<Table id="items" items="{SO_2_SOITEM}">\
	<Text id="itemNote" text="{Note}"/>\
</Table>',
			that = this;

		// code under test
		oModel.attachPropertyChange(function (oEvent) {
			oPromise = oEvent.getParameter("promise");
		});

		this.expectRequest("SalesOrderList"
				+ "?$expand=SO_2_SOITEM($select=ItemPosition,Note,SalesOrderID)"
				+ "&$select=Note,SalesOrderID"
				+ "&$skip=0&$top=100", {
				value : [{
					Note : "SO_1",
					SalesOrderID : "1",
					SO_2_SOITEM : [{
						ItemPosition : "10",
						Note : "Item_10",
						SalesOrderID : "1"
					}]
				}]
			})
			.expectChange("note", ["SO_1"])
			.expectChange("itemNote", []);

		return this.createView(assert, sView, oModel).then(function () {
			var oOrdersTable = that.oView.byId("orders"),
				oOrdersBinding = oOrdersTable.getBinding("items");

			that.expectChange("note", ["SO_1 changed"])
				.expectChange("note", ["SO_1"]);

			oOrdersTable.getItems()[0].getCells()[0].getBinding("value").setValue("SO_1 changed");

			assert.ok(oPromise, "propertyChange fired sync");

			// code under test
			assert.ok(oOrdersBinding.hasPendingChanges());

			that.expectChange("itemNote", ["Item_10"]);

			// Observe hasPendingChanges while the child binding is checking whether it can use the
			// parent cache
			that.oView.byId("items").setBindingContext(oOrdersBinding.getCurrentContexts()[0]);

			// code under test
			assert.ok(oOrdersBinding.hasPendingChanges());

			that.expectCanceledError("Failed to update path /SalesOrderList('1')/Note",
					"Request canceled: PATCH SalesOrderList('1'); group: $auto");

			return Promise.all([
				oOrdersBinding.resetChanges().then(function () {
					// code under test
					assert.notOk(oOrdersBinding.hasPendingChanges());
				}),
				checkCanceled(assert, oPromise),
				that.waitForChanges(assert)
			]);
		});
	});

	//*********************************************************************************************
	// Scenario: Show that a property binding for the first element of an expanded collection works
	// w/o sending own requests, even if system query options are present for that expand.
	// BCP: 2280025746
	QUnit.test("BCP: 2280025746", function (assert) {
		var sView = '\
<Table items="{path : \'/SalesOrderList\', parameters : {\
		$expand : {\
			SO_2_SOITEM : {\
				$count : true,\
				$filter : \'Note ne \\\'\\\'\',\
				$levels : 1,\
				$orderby : \'ItemPosition\',\
				$search : \'covfefe\'\
			}\
		}\
	}}">\
	<Text id="id" text="{SalesOrderID}"/>\
	<Text id="item0Note" text="{SO_2_SOITEM/0/Note}"/>\
</Table>';

		this.expectRequest("SalesOrderList?$expand=SO_2_SOITEM($count=true;$filter=Note ne ''"
				+ ";$levels=1;$orderby=ItemPosition;$search=covfefe;$select=ItemPosition,Note"
				+ ",SalesOrderID)&$select=SalesOrderID&$skip=0&$top=100", {
				value : [{
					SalesOrderID : "1",
					SO_2_SOITEM : [{
						"@odata.count" : "1",
						ItemPosition : "10",
						Note : "covfefe",
						SalesOrderID : "1"
					}]
				}]
			})
			.expectChange("id", ["1"])
			.expectChange("item0Note", ["covfefe"]);

		return this.createView(assert, sView,
			this.createSalesOrdersModel({autoExpandSelect : true}));
	});

	//*********************************************************************************************
	// Scenario: Create a new entity without using a UI and persist it.
	// ODataModel#hasPendingChanges and ODataListBinding#hasPendingChanges work as expected even if
	// late properties below a list binding want to reuse the parent binding's cache. Relative list
	// binding without an own cache is necessary because determination whether cache can be used or
	// not is async.
	// Resetting pending changes works synchronously.
	// JIRA: CPOUI5UISERVICESV3-1981, CPOUI5UISERVICESV3-1994
	//
	// CPOUI5UISERVICESV3-1994 is obsolete now because the cache promise remains resolved and
	// resetChangesForPath can always run synchronously
	// BCP: 2370141835
[
	// late dependent binding does not influence hasPendingChanges for a parent list binding with a
	// persisted created entity.
	function (assert, oModel, oBinding, oCreatedContext) {
		this.expectChange("note", "New");

		this.oView.byId("form").setBindingContext(oCreatedContext);

		// code under test
		assert.notOk(oModel.hasPendingChanges());
		assert.notOk(oBinding.hasPendingChanges());

		return this.waitForChanges(assert);
	},
	// modify a persisted created entity; hasPendingChanges is not influenced by late properties;
	// resetChanges reverts changes synchronously (BCP: 2370141835)
	function (assert, oModel, oBinding, oCreatedContext) {
		var oPropertyBinding = oModel.bindProperty("Note", oCreatedContext);

		oPropertyBinding.initialize();
		oPropertyBinding.setValue("Modified"); // no change event; reset is done synchronously
		this.oView.byId("form").setBindingContext(oCreatedContext);

		// code under test
		assert.ok(oModel.hasPendingChanges());
		assert.ok(oBinding.hasPendingChanges());

		this.expectCanceledError("Failed to update path /SalesOrderList('43')/Note",
				"Request canceled: PATCH SalesOrderList('43'); group: $auto")
			.expectChange("note", "New");

		return Promise.all([
			// code under test
			oBinding.resetChanges().then(function () {
				// code under test
				assert.notOk(oModel.hasPendingChanges());
				assert.notOk(oBinding.hasPendingChanges());
			}),
			this.waitForChanges(assert)
		]);
	}
].forEach(function (fnTest, i) {
	var sTitle = "hasPendingChanges/resetChanges: late properties for a list binding without a UI"
			+ " and with a persisted created entity, #" + i;

	QUnit.test(sTitle, function (assert) {
		var oCreatedContext,
			oListBindingWithoutUI,
			oModel = this.createSalesOrdersModel({autoExpandSelect : true}),
			sView = '\
<FlexBox id="form">\
	<Text id="note" text="{Note}"/>\
	<Table id="items" items="{SO_2_SOITEM}">\
		<Text text="{ItemPosition}"/>\
	</Table>\
</FlexBox>',
			that = this;

		oListBindingWithoutUI = oModel.bindList("/SalesOrderList", null, [], [],
			{$expand : {SO_2_SOITEM : null}});

		this.expectChange("note");

		return this.createView(assert, sView, oModel).then(function () {
			that.expectRequest({
					method : "POST",
					url : "SalesOrderList",
					payload : {}
				}, {
					Note : "New",
					SalesOrderID : "43"
				})
				.expectRequest("SalesOrderList('43')?$expand=SO_2_SOITEM", {
					Note : "New",
					SalesOrderID : "43",
					SO_2_SOITEM : []
				});

			oCreatedContext = oListBindingWithoutUI.create();

			// code under test
			assert.ok(oModel.hasPendingChanges());
			assert.ok(oListBindingWithoutUI.hasPendingChanges());

			return Promise.all([
				oCreatedContext.created(),
				that.waitForChanges(assert)
			]);
		}).then(function () {
			// code under test
			assert.notOk(oModel.hasPendingChanges());
			assert.notOk(oListBindingWithoutUI.hasPendingChanges());

			return fnTest.call(that, assert, oModel, oListBindingWithoutUI, oCreatedContext);
		});
	});
});

	//*********************************************************************************************
	// Scenario: Create a new entity without using a UI and reset it immediately. No request is
	// added to the queue and ODataModel#hasPendingChanges and ODataListBinding#hasPendingChanges
	// work as expected.
	// JIRA: CPOUI5UISERVICESV3-1994
	//
	// hasPendingChanges(true) must not be affected (SNOW: DINC0025951)
	QUnit.test("create an entity and immediately reset changes (no UI) V3-1994", function (assert) {
		var // use autoExpandSelect so that the cache is created asynchronously
			oModel = this.createSalesOrdersModel({autoExpandSelect : true}),
			that = this;

		return this.createView(assert, "", oModel).then(function () {
			var oListBindingWithoutUI = oModel.bindList("/SalesOrderList"),
				oCreatedPromise = oListBindingWithoutUI.create({}, true).created();

			assert.ok(oModel.hasPendingChanges());
			assert.ok(oListBindingWithoutUI.hasPendingChanges());
			assert.notOk(oListBindingWithoutUI.hasPendingChanges(true), "SNOW: DINC0025951");
			assert.strictEqual(oListBindingWithoutUI.getLength(), 1 + 10/*length is not final