function respond(iStart, iLength, bWithPromise) {
			const aElements = [];
			const iEnd = Math.min(iStart + iLength, 30);
			for (let i = iStart; i < iEnd; i += 1) {
				aElements.push({
					__metadata : {uri : "/SalesOrderSet('" + i + "')"},
					SalesOrderID : i
				});
			}

			return bWithPromise ? {data : {results : aElements}, statusCode : 200} : {results : aElements};
		}
******************************************************************************************
	// Scenario: If the server uses server side paging and the ODataTreeBinding is in "Client" mode all data is
	// requested.
	// BCP: 2270014869
	QUnit.test("ODataTreeBinding: _loadCompleteTreeWithAnnotations loads complete tree", function (assert) {
		const oModel = createSpecialCasesModel();
		const sView = '\
<t:TreeTable id="table" visibleRowCount="4">\
	<Text text="{MaintenanceOrder}" />\
</t:TreeTable>';
		let iDataRequested = 0;
		let iDataReceived = 0;
		let oTable;

		return this.createView(assert, sView, oModel).then(() => {
			this.expectHeadRequest()
				.expectRequest("C_RSHMaintSchedSmltdOrdAndOp?"
						+ "$select=MaintenanceOrder,OrderOperationRowLevel,OrderOperationParentRowID,"
							+ "OrderOperationRowID,OrderOperationIsExpanded&"
						+ "$orderby=OrderOperationRowID asc", {
					results : [{
						__metadata: {uri: "C_RSHMaintSchedSmltdOrdAndOp('id1')"},
						MaintenanceOrder: "1",
						OrderOperationIsExpanded: "leaf",
						OrderOperationParentRowID: "",
						OrderOperationRowID: "id1",
						OrderOperationRowLevel: 0
					}],
					__next : "next link"
				}).expectRequest("C_RSHMaintSchedSmltdOrdAndOp?$skip=1&$top=2&"
						+ "$select=MaintenanceOrder,OrderOperationRowLevel,OrderOperationParentRowID,"
							+ "OrderOperationRowID,OrderOperationIsExpanded&"
						+ "$orderby=OrderOperationRowID asc", {
					results : [{
						__metadata: {uri: "C_RSHMaintSchedSmltdOrdAndOp('id2')"},
						MaintenanceOrder: "2",
						OrderOperationIsExpanded: "leaf",
						OrderOperationParentRowID: "",
						OrderOperationRowID: "id2",
						OrderOperationRowLevel: 0
					}, {
						__metadata: {uri: "C_RSHMaintSchedSmltdOrdAndOp('id3')"},
						MaintenanceOrder: "3",
						OrderOperationIsExpanded: "leaf",
						OrderOperationParentRowID: "",
						OrderOperationRowID: "id3",
						OrderOperationRowLevel: 0
					}]
				}).expectRequest("C_RSHMaintSchedSmltdOrdAndOp?$skip=3&$top=2&"
						+ "$select=MaintenanceOrder,OrderOperationRowLevel,OrderOperationParentRowID,"
							+ "OrderOperationRowID,OrderOperationIsExpanded&"
						+ "$orderby=OrderOperationRowID asc", {
					results : [{
						__metadata: {uri: "C_RSHMaintSchedSmltdOrdAndOp('id4')"},
						MaintenanceOrder: "4",
						OrderOperationIsExpanded: "leaf",
						OrderOperationParentRowID: "",
						OrderOperationRowID: "id4",
						OrderOperationRowLevel: 0
					}]
				});
			oTable = this.oView.byId("table");
			oTable.bindRows({
				events: {
					dataReceived: (oEvent) => {
						const oEventData = oEvent.getParameter("data");

						iDataReceived += 1;
						// responses are merged
						assert.strictEqual(oEventData.results.length, 4);
						oEventData.results.forEach((oData, i) => {
							assert.strictEqual(oData.OrderOperationRowID, "id" + (i + 1));
						});
					},
					dataRequested: () => {iDataRequested += 1;}
				},
				filter: [new Filter("OrderOperationRowLevel", FilterOperator.EQ, 1)],
				parameters: {
					countMode: CountMode.Inline,
					operationMode: "Client",
					select: "MaintenanceOrder",
					treeAnnotationProperties: {
						hierarchyDrillStateFor: "OrderOperationIsExpanded",
						hierarchyLevelFor: "OrderOperationRowLevel",
						hierarchyNodeFor: "OrderOperationRowID",
						hierarchyParentNodeFor : "OrderOperationParentRowID"
					}
				},
				path: "C_RSHMaintSchedSmltdOrdAndOp",
				sorter: [new Sorter("OrderOperationRowID", false)]
			});

			// reduce the maximum $top value for test purpuses only
			oTable.getBinding("rows").iMaximumTopValue = 2;

			// code under test - request the complete tree
			oTable.setBindingContext(new Context(oModel, "/"));

			return this.waitForChanges(assert);
		}).then(() => {
			assert.deepEqual(getTableContent(oTable), [["1"], ["2"], ["3"], ["4"]]);
			assert.strictEqual(iDataRequested, 1, "dataRequested fired once");
			assert.strictEqual(iDataReceived, 1, "dataReceived fired once");

			return this.waitForChanges(assert);
		});
	});

	//*********************************************************************************************
	// Scenario: If the server uses server side paging and the ODataTreeBinding is in "Client" mode all data is
	// requested. The last request returns no data.
	// BCP: 2270014869
	QUnit.test("ODataTreeBinding: _loadCompleteTreeWithAnnotations loads complete tree, no data in last request",
			function (assert) {
		const oModel = createSpecialCasesModel();
		const sView = '\
<t:TreeTable id="table" visibleRowCount="2">\
	<Text text="{MaintenanceOrder}" />\
</t:TreeTable>';
		let iDataRequested = 0;
		let iDataReceived = 0;
		let oTable;

		return this.createView(assert, sView, oModel).then(() => {
			this.expectHeadRequest()
				.expectRequest("C_RSHMaintSchedSmltdOrdAndOp?"
						+ "$select=MaintenanceOrder,OrderOperationRowLevel,OrderOperationParentRowID,"
							+ "OrderOperationRowID,OrderOperationIsExpanded&"
						+ "$orderby=OrderOperationRowID asc", {
					results : [{
						__metadata: {uri: "C_RSHMaintSchedSmltdOrdAndOp('id1')"},
						MaintenanceOrder: "1",
						OrderOperationIsExpanded: "leaf",
						OrderOperationParentRowID: "",
						OrderOperationRowID: "id1",
						OrderOperationRowLevel: 0
					}],
					__next : "next link"
				}).expectRequest("C_RSHMaintSchedSmltdOrdAndOp?$skip=1&$top=1&"
						+ "$select=MaintenanceOrder,OrderOperationRowLevel,OrderOperationParentRowID,"
							+ "OrderOperationRowID,OrderOperationIsExpanded&"
						+ "$orderby=OrderOperationRowID asc", {
					results : [{
						__metadata: {uri: "C_RSHMaintSchedSmltdOrdAndOp('id2')"},
						MaintenanceOrder: "2",
						OrderOperationIsExpanded: "leaf",
						OrderOperationParentRowID: "",
						OrderOperationRowID: "id2",
						OrderOperationRowLevel: 0
					}]
				}).expectRequest("C_RSHMaintSchedSmltdOrdAndOp?$skip=2&$top=1&"
						+ "$select=MaintenanceOrder,OrderOperationRowLevel,OrderOperationParentRowID,"
							+ "OrderOperationRowID,OrderOperationIsExpanded&"
						+ "$orderby=OrderOperationRowID asc", {
					results : []
				});
			oTable = this.oView.byId("table");
			oTable.bindRows({
				events: {
					dataReceived: (oEvent) => {
						const oEventData = oEvent.getParameter("data");

						iDataReceived += 1;
						// responses are merged
						assert.strictEqual(oEventData.results.length, 2);
						oEventData.results.forEach((oData, i) => {
							assert.strictEqual(oData.OrderOperationRowID, "id" + (i + 1));
						});
					},
					dataRequested: () => {iDataRequested += 1;}
				},
				filter: [new Filter("OrderOperationRowLevel", FilterOperator.EQ, 0)], // must not be in URL params
				parameters: {
					countMode: CountMode.Inline,
					operationMode: "Client",
					select: "MaintenanceOrder",
					treeAnnotationProperties: {
						hierarchyDrillStateFor: "OrderOperationIsExpanded",
						hierarchyLevelFor: "OrderOperationRowLevel",
						hierarchyNodeFor: "OrderOperationRowID",
						hierarchyParentNodeFor : "OrderOperationParentRowID"
					}
				},
				path: "C_RSHMaintSchedSmltdOrdAndOp",
				sorter: [new Sorter("OrderOperationRowID", false)]
			});

			// reduce the maximum $top value for test purpuses only
			oTable.getBinding("rows").iMaximumTopValue = 1;

			// code under test - request the complete tree
			oTable.setBindingContext(new Context(oModel, "/"));

			return this.waitForChanges(assert);
		}).then(() => {
			assert.deepEqual(getTableContent(oTable), [["1"], ["2"]]);
			assert.strictEqual(iDataRequested, 1, "dataRequested fired once");
			assert.strictEqual(iDataReceived, 1, "dataReceived fired once");

			return this.waitForChanges(assert);
		});
	});

	//*********************************************************************************************
	// Scenario: Annotation changes are applied to root service's metadata and annotation files
	// JIRA: CPOUI5MODELS-1783
	QUnit.test("CPOUI5MODELS-1783: setAnnotationChangePromise", async function (assert) {
		const oModel = createSalesOrdersModel({
			annotationURI : "/sap/opu/odata/sap/ZUI5_GWSAMPLE_BASIC/" + "ZUI5_GWSAMPLE_BASIC.annotations.xml"
		});

		await this.createView(assert, "", oModel);

		const aAnnotationChanges = [{ // override lifted V2 annotation from metadata.xml
			path : "/dataServices/schema/0/entityType/[${name}==='BusinessPartner']/property"
				+ "/[${name}==='LegalForm']/com.sap.vocabularies.Common.v1.Label",
			value : {String: "*My* Legal Form"} // original: "Legal Form"
		}, { // add a new annotation
			path : "/dataServices/schema/0/entityType/[${name}==='BusinessPartner']/property"
				+ "/[${name}==='LegalForm']/com.sap.vocabularies.Common.v1.QuickInfo",
			value : {String: "Quick Info for Legal Form"} // original: not available
		}, { // override annotation contained in metadata.xml
			path : "/dataServices/schema/0/entityType/[${name}==='BusinessPartner']/property"
				+ "/[${name}==='FaxNumber']/com.sap.vocabularies.Common.v1.Label",
			value : {String: "*My* Fax Number"} // original: "Fax Number from metadata annotation"
		}, { // override annotation contained in ZUI5_GWSAMPLE_BASIC.annotations.xml
			path : "/dataServices/schema/0/entityType/[${name}==='BusinessPartner']/property"
				+ "/[${name}==='PhoneNumber']/com.sap.vocabularies.Common.v1.Label",
			value : {String: "*My* Phone Number"} // original: "Phone No. from annotation file"
		}, { // override text arrangement annotation
			path : "/dataServices/schema/0/entityType/[${name}==='SalesOrder']/property"
				+ "/[${name}==='BillingStatus']/com.sap.vocabularies.Common.v1.Text"
				+ "/com.sap.vocabularies.UI.v1.TextArrangement",
			value : {EnumMember: "com.sap.vocabularies.UI.v1.TextArrangementType/TextLast"} // original: TextFirst
		}, { // add new text annotation
			path : "/dataServices/schema/0/entityType/[${name}==='SalesOrder']/property"
				+ "/[${name}==='DeliveryStatus']/com.sap.vocabularies.Common.v1.Text",
			value : {Path: "DeliveryStatusDescription"} // new Text annotation for DeliveryStatus
		}, { // add new text arrangement annotation
			path : "/dataServices/schema/0/entityType/[${name}==='SalesOrder']/property"
				+ "/[${name}==='DeliveryStatus']/com.sap.vocabularies.Common.v1.Text"
				+ "/com.sap.vocabularies.UI.v1.TextArrangement",
			value : {EnumMember: "com.sap.vocabularies.UI.v1.TextArrangementType/TextFirst"} // new text arrangement
		}, { // change the Label of a record within a LineItem annotation
			path : "/dataServices/schema/0/entityType/[${name}==='SalesOrder']/com.sap.vocabularies.UI.v1.LineItem"
				+ "/[${Value/Path}==='DeliveryStatus']/Label",
			value : {String: "Delivery Status (LineItem overwritten)"} // original: "Delivery Status (LineItem)"
		}, { // add a Label for a record within a LineItem annotation
			path : "/dataServices/schema/0/entityType/[${name}==='SalesOrder']/com.sap.vocabularies.UI.v1.LineItem"
				+ "/[${Value/Path}==='BillingStatus']/Label",
			value : {String: "Billing Status (added to LineItem record)"} // new Label
		}, { // no error log for invalid paths
			path : "/dataServices/schema/0/entityType/[${name}==='Foo']/com.sap.vocabularies.UI.v1.LineItem"
				+ "/[${Value/Path}==='Bar']/Label",
			value : {String: "Cannot be set"}
		}];
		const aOriginalAnnotationChanges = JSON.parse(JSON.stringify(aAnnotationChanges));

		// code under test
		oModel.setAnnotationChangePromise(Promise.resolve(aAnnotationChanges));

		const oMetaModel = oModel.getMetaModel();
		await oMetaModel.loaded();
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='BusinessPartner']"
				+ "/property/[${name}==='LegalForm']/com.sap.vocabularies.Common.v1.Label/String"),
			"*My* Legal Form");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='BusinessPartner']"
				+ "/property/[${name}==='LegalForm']/com.sap.vocabularies.Common.v1.QuickInfo/String"),
			"Quick Info for Legal Form");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='BusinessPartner']"
				+ "/property/[${name}==='FaxNumber']/com.sap.vocabularies.Common.v1.Label/String"),
			"*My* Fax Number");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='BusinessPartner']"
				+ "/property/[${name}==='PhoneNumber']/com.sap.vocabularies.Common.v1.Label/String"),
			"*My* Phone Number");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='SalesOrder']"
				+ "/property/[${name}==='BillingStatus']/com.sap.vocabularies.Common.v1.Text"
				+ "/com.sap.vocabularies.UI.v1.TextArrangement/EnumMember"),
			"com.sap.vocabularies.UI.v1.TextArrangementType/TextLast");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='SalesOrder']"
				+ "/property/[${name}==='DeliveryStatus']/com.sap.vocabularies.Common.v1.Text/Path"),
			"DeliveryStatusDescription");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='SalesOrder']"
				+ "/property/[${name}==='DeliveryStatus']/com.sap.vocabularies.Common.v1.Text"
				+ "/com.sap.vocabularies.UI.v1.TextArrangement/EnumMember"),
			"com.sap.vocabularies.UI.v1.TextArrangementType/TextFirst");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='SalesOrder']"
				+ "/com.sap.vocabularies.UI.v1.LineItem/[${Value/Path}==='DeliveryStatus']/Label/String"),
			"Delivery Status (LineItem overwritten)");
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='SalesOrder']"
				+ "/com.sap.vocabularies.UI.v1.LineItem/[${Value/Path}==='BillingStatus']/Label/String"),
			"Billing Status (added to LineItem record)");
		assert.strictEqual(
			oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='SalesOrder']"
				+ "/property/[${name}==='BillingStatus']/com.sap.vocabularies.Common.v1.Text/Path"),
			"BillingStatusDescription"); // still untouched
		assert.strictEqual(oMetaModel.getProperty("/dataServices/schema/0/entityType/[${name}==='Foo']"), undefined);
		assert.deepEqual(aAnnotationChanges, aOriginalAnnotationChanges, "no changes in input array");

		return this.waitForChanges(assert);
	});

	//*********************************************************************************************
	// Scenario: If meta data for value lists are loaded on demand, ensure that the annotation changes are applied.
	// JIRA: CPOUI5MODELS-1789
	QUnit.test("CPOUI5MODELS-1789: setAnnotationChangePromise after value lists are loaded", async function (assert) {
		const oModel = createSalesOrdersModel({
			annotationURI : "/sap/opu/odata/sap/ZUI5_GWSAMPLE_BASIC/" + "ZUI5_GWSAMPLE_BASIC.annotations.xml"
		});
		await this.createView(assert, "", oModel);

		const sPrefixVHSexEntity = "/dataServices/schema/0/entityType/[${name}==='VH_Sex']";
		const sAnnotationPathVHSexShortTextLabel = sPrefixVHSexEntity
			+ "/property/[${name}==='Shorttext']/com.sap.vocabularies.Common.v1.Label";
		const sPrefixBusinessPartnerProperties = "/dataServices/schema/0/entityType/[${name}==='BusinessPartner']"
			+ "/property";
		const sPrefixContactProperties = "/dataServices/schema/0/entityType/[${name}==='Contact']/property";
		const aAnnotationChanges = [{ // override lifted V2 annotation from metadata.xml
			path : sPrefixBusinessPartnerProperties + "/[${name}==='LegalForm']/com.sap.vocabularies.Common.v1.Label",
			value : {String: "*My* Legal Form"} // original: "Legal Form"
		}, { // override annotation contained in metadata.xml
			path : sPrefixBusinessPartnerProperties + "/[${name}==='FaxNumber']/com.sap.vocabularies.Common.v1.Label",
			value : {String: "*My* Fax Number"} // original: "Fax Number from metadata annotation"
		}, { // override annotation contained in ZUI5_GWSAMPLE_BASIC.annotations.xml
			path : sPrefixBusinessPartnerProperties + "/[${name}==='PhoneNumber']/com.sap.vocabularies.Common.v1.Label",
			value : {String: "*My* Phone Number"} // original: "Phone No. from annotation file"
		}, { // annotation path can be resolved only after metadata for value list is loaded
			path : sAnnotationPathVHSexShortTextLabel,
			value : {String: "*My* Short Descript."} // original: "Short Descript."
		}, { // changed annotations must not be overwritten when metadata for a value list is merged, especially if
			 // the metadata for the value list contains an annotation that has been changed by annotation changes
			 // already
			path : sPrefixContactProperties + "/[${name}==='Sex']/com.sap.vocabularies.Common.v1.Label",
			value : {String: "Sex (Annotation Changes)"} // original: "Sex"
		}];

		// code under test
		oModel.setAnnotationChangePromise(Promise.resolve(aAnnotationChanges));

		const oMetaModel = oModel.getMetaModel();
		await oMetaModel.loaded();
		// annotation changes that have been applied when the meta model is created
		assert.strictEqual(oMetaModel.getProperty(sPrefixBusinessPartnerProperties
				+ "/[${name}==='LegalForm']/com.sap.vocabularies.Common.v1.Label/String"),
			"*My* Legal Form");
		assert.strictEqual(oMetaModel.getProperty(sPrefixBusinessPartnerProperties
				+ "/[${name}==='FaxNumber']/com.sap.vocabularies.Common.v1.Label/String"),
			"*My* Fax Number");
		assert.strictEqual(oMetaModel.getProperty(sPrefixBusinessPartnerProperties
				+ "/[${name}==='PhoneNumber']/com.sap.vocabularies.Common.v1.Label/String"),
			"*My* Phone Number");
		assert.strictEqual(oMetaModel.getProperty(sPrefixBusinessPartnerProperties
				+ "/[${name}==='PhoneNumber']/com.sap.vocabularies.Common.v1.Label/String"),
			"*My* Phone Number");
		assert.strictEqual(oMetaModel.getProperty(sPrefixContactProperties
				+ "/[${name}==='Sex']/com.sap.vocabularies.Common.v1.Label/String"),
			"Sex (Annotation Changes)");
		// VH_Sex Entity type not yet loaded - don't use full annotation path to avoid logging warnings
		assert.strictEqual(oMetaModel.getProperty(sPrefixVHSexEntity), undefined);

		// code under test - load value list for Contact/Sex
		const oMetaContextForSexProperty = oMetaModel.getMetaContext("/ContactSet('~guid')/Sex");
		const oValueHelpPromise = oMetaModel.getODataValueLists(oMetaContextForSexProperty);

		return oValueHelpPromise.then(() => {
			assert.strictEqual(oMetaModel.getProperty(sAnnotationPathVHSexShortTextLabel + "/String"),
				"*My* Short Descript.");
			assert.strictEqual(oMetaModel.getProperty(sPrefixVHSexEntity
					+ "/property/[${name}==='Sex']/com.sap.vocabularies.Common.v1.Label/String"),
				"Sex (value list)");
			// annotation changes that have been applied after the value list is loaded have to be unchanged
			assert.strictEqual(oMetaModel.getProperty(sPrefixBusinessPartnerProperties
					+ "/[${name}==='LegalForm']/com.sap.vocabularies.Common.v1.Label/String"),
				"*My* Legal Form");
			assert.strictEqual(oMetaModel.getProperty(sPrefixBusinessPartnerProperties
					+ "/[${name}==='FaxNumber']/com.sap.vocabularies.Common.v1.Label/String"),
				"*My* Fax Number");
			assert.strictEqual(oMetaModel.getProperty(sPrefixBusinessPartnerProperties
					+ "/[${name}==='PhoneNumber']/com.sap.vocabularies.Common.v1.Label/String"),
				"*My* Phone Number");
			assert.strictEqual(oMetaModel.getProperty(sPrefixContactProperties
					+ "/[${name}==='Sex']/com.sap.vocabularies.Common.v1.Label/String"),
				"Sex (Annotation Changes)");
		});
	});

	//*********************************************************************************************
	// Scenario: If there is a pending request and the application switches the binding context, the pending
	// request must be aborted and the dataReceived event has to be fired, e.g. to hide a busy indicator.
	// SNOW: DINC0246364
	QUnit.test("DINC0246364: dataReveived for aborted requests after context change", function (assert) {
		const oModel = createSalesOrdersModel({});
		const sView = `
<FlexBox id="form" binding="{/SalesOrderSet('1')}">
	<Text id="salesOrderId" text="{SalesOrderID}" />
	<Table id="table" items="{ToLineItems}">
		<Text id="itemPosition" text="{ItemPosition}" />
	</Table>
</FlexBox>`;

		this.expectHeadRequest()
			.expectRequest("SalesOrderSet('1')", {
				SalesOrderID : "1"
			})
			.expectRequest("SalesOrderSet('1')/ToLineItems?$skip=0&$top=100", {
				results : [{
					__metadata : {
						uri : "/SalesOrderLineItemSet(SalesOrderID='1',ItemPosition='10')"
					},
					SalesOrderID : "1",
					ItemPosition : "10"
				}, {
					__metadata : {
						uri : "/SalesOrderLineItemSet(SalesOrderID='1',ItemPosition='20')"
					},
					SalesOrderID : "1",
					ItemPosition : "20"
				}]
			});

		return this.createView(assert, sView).then((oView) => {
			const oTableBinding = this.oView.byId("table").getBinding("items");
			const oEventHandlers = {onDataRequested() {}, onDataReceived() {}};
			const oEventHandlersMock = this.mock(oEventHandlers);
			oEventHandlersMock.expects("onDataRequested").once();
			// the data received event has to be fired to disable the busy indicator
			oEventHandlersMock.expects("onDataReceived").once();
			oTableBinding.attachDataRequested(oEventHandlers.onDataRequested);
			oTableBinding.attachDataReceived(oEventHandlers.onDataReceived);
			// no expectRequest as the request is cancelled before it is created

			// code under test - first refresh the list binding to create a pending request
			oTableBinding.refresh(true);

			// code under test - then unbind the form which cancels the pending request
			this.oView.byId("form").unbindElement();

			return Promise.all([
				// request creation is done async, wait long enough until the request is aborted
				oModel.getMetaModel().loaded(),
				this.waitForChanges(assert)
			]);
		});
	});

	//*********************************************************************************************
	// Scenario: Allow loading of value lists for function import parameters on demand.
	// JIRA: CPOUI5MODELS-1746
	QUnit.test("CPOUI5MODELS-1746: load value list for function import parameter on demand", async function (assert) {
		const oModel = createSalesOrdersModelSpecialFunctionImports();
		await this.createView(assert, "", oModel);
		const oMetaModel = oModel.getMetaModel();
		await oMetaModel.loaded();

		// code under test - load value list for function import parameter
		const oFunctionImportParameterMetaContext = oMetaModel.getFunctionImportParameterContext(
			"Function_With_ValueList_For_Parameter", "Parameter_With_On_Demand_ValueList");
		const oParameter = oMetaModel.getObject(oFunctionImportParameterMetaContext.getPath());

		assert.strictEqual(oParameter["com.sap.vocabularies.Common.v1.Label"].String,
			"Parameter with on demand ValueList");
		assert.strictEqual(oParameter["com.sap.vocabularies.Common.v1.ValueList"], undefined);

		// code under test
		const oValueHelpPromise = oMetaModel.getODataValueLists(oFunctionImportParameterMetaContext);

		return oValueHelpPromise.then((mValueLists) => {
			const oParameter = oMetaModel.getObject(oFunctionImportParameterMetaContext.getPath());

			assert.strictEqual(oParameter["com.sap.vocabularies.Common.v1.Label"].String,
				"Parameter with on demand ValueList");
			assert.deepEqual(oParameter["com.sap.vocabularies.Common.v1.ValueList"], mValueLists[""]);
		});
	});

	//*********************************************************************************************
	// Tests for bExpectMore simulating a control using a list binding. Use a length of 2, a prefetch of 4, and a
	// collection length of 30. The tests do not use $count and find out about the length via short reads.
	// JIRA: CPOUI5MODELS-1804
	(function () {
		/**
Creates a response with SalesOrderSet entries for the given range. The collection length is assumed to be 30.

@param {number} iStart The start index
@param {number} iLength The length
@param {boolean} [bWithPromise=false] Whether response is wrapped in a promise
@returns {object} The response