function expectVisitEtc(aPromises) {
					that.mock(oBinding).expects("visitSideEffects")
						.withExactArgs(sGroupId, sinon.match.same(aPaths),
							sinon.match.same(oContext), aPromises)
						.callsFake(function (_sGroupId, _aPaths, _oContext, aPromises0) {
							aPromises0.push(Promise.resolve());
							aPromises0.push(Promise.reject(oCanceledError));
							if (bRecursionRejects) {
								aPromises0.push(Promise.reject(oError));
							}
						});
					that.mock(oBinding).expects("refreshDependentListBindingsWithoutCache")
						.exactly(bRecursionRejects ? 0 : 1).withExactArgs().resolves("~");
				}
******************************************************************************************
	QUnit.test("getParameterContext bound operation (context switch)", function (assert) {
		var oBinding = this.bindContext("schema.Operation(...)");

		// code under test
		assert.strictEqual(oBinding.oParameterContext, null);

		// code under test - context switch
		oBinding.setContext(Context.create(this.oModel, {}, "/Employee('42')"));
		assert.ok(oBinding.oParameterContext);
		assert.strictEqual(
			oBinding.oParameterContext.getPath(),
			"/Employee('42')/schema.Operation(...)/$Parameter"
		);

		this.mock(oBinding.oParameterContext).expects("destroy").withExactArgs();

		this.mock(oBinding).expects("checkSuspended").withExactArgs(true);
		oBinding.setContext(null);

		// code under test
		assert.strictEqual(oBinding.oParameterContext, null);
	});

	//*********************************************************************************************
	[{
		sPath : undefined,
		sResult : undefined
	}, {
		sPath : "/TEAMS('ABC-1')",
		sResult : "/TEAMS('ABC-1')"
	}, {
		sPath : "/TEAMS($uid=id-1-23)",
		aFetchValues : [{
			oEntity : {},
			sPath : "/TEAMS($uid=id-1-23)",
			sPredicate : "('13')"
		}],
		sResult : "/TEAMS('13')"
	}, {
		sPath : "/TEAMS($uid=id-1-23)/TEAM_2_EMPLOYEES",
		aFetchValues : [{
			oEntity : {},
			sPath : "/TEAMS($uid=id-1-23)",
			sPredicate : "('13')"
		}],
		sResult : "/TEAMS('13')/TEAM_2_EMPLOYEES"
	}, {
		sPath : "/TEAMS($uid=id-1-23)/TEAM_2_EMPLOYEES($uid=id-1-24)",
		aFetchValues : [{
			oEntity : {},
			sPath : "/TEAMS($uid=id-1-23)",
			sPredicate : "('13')"
		}, {
			oEntity : {},
			sPath : "/TEAMS($uid=id-1-23)/TEAM_2_EMPLOYEES($uid=id-1-24)",
			sPredicate : "('6')"
		}],
		sResult : "/TEAMS('13')/TEAM_2_EMPLOYEES('6')"
	}].forEach(function (oFixture, i) {
		QUnit.test("getResolvedPathWithReplacedTransientPredicates: " + i, function (assert) {
			var oContext = Context.create(this.oModel, {}, "/TEAMS"),
				oContextMock = this.mock(oContext),
				oBinding = this.bindContext("foo", oContext),
				oHelperMock = this.mock(_Helper);

			this.mock(oBinding).expects("getResolvedPath").withExactArgs().returns(oFixture.sPath);

			if (oFixture.aFetchValues) {
				oFixture.aFetchValues.forEach(function (oFetchValue) {
					oContextMock.expects("getValue").withExactArgs(oFetchValue.sPath)
						.returns(oFetchValue.oEntity);
					oHelperMock.expects("getPrivateAnnotation")
						.withExactArgs(sinon.match.same(oFetchValue.oEntity), "predicate")
						.returns(oFetchValue.sPredicate);
				});
			}

			// code under test
			assert.strictEqual(oBinding.getResolvedPathWithReplacedTransientPredicates(),
				oFixture.sResult);
		});
	});

	//*********************************************************************************************
[{}, undefined].forEach(function (oEntity, i) {
	QUnit.test("getResolvedPathWithReplacedTransientPredicates error: no key predicate " + i,
			function (assert) {
		var sPath = "/TEAMS($uid=id-1-23)",
			oContext = Context.create(this.oModel, {}, sPath),
			oBinding = this.bindContext("", oContext);

		this.mock(oBinding).expects("getResolvedPath").withExactArgs().returns(sPath);
		this.mock(oContext).expects("getValue").withExactArgs(sPath).returns(oEntity);
		this.mock(_Helper).expects("getPrivateAnnotation").exactly(oEntity ? 1 : 0)
			.withExactArgs(sinon.match.same(oEntity), "predicate")
			.returns(undefined);

		// code under test
		assert.throws(function () {
			oBinding.getResolvedPathWithReplacedTransientPredicates();
		}, new Error("No key predicate known at " + sPath));
	});
});

	//*********************************************************************************************
	QUnit.test("computeOperationQueryOptions", function (assert) {
		var oBinding = this.bindContext("bound.Operation(...)"),
			mMergedQueryOptions = {},
			mQueryOptions = {};

		this.mock(oBinding).expects("getQueryOptionsFromParameters").withExactArgs()
			.returns(mQueryOptions);
		this.mock(Object).expects("assign")
			.withExactArgs({}, sinon.match.same(oBinding.oModel.mUriParameters),
				sinon.match.same(mQueryOptions))
			.returns(mMergedQueryOptions);

		// code under test
		assert.strictEqual(oBinding.computeOperationQueryOptions(), mMergedQueryOptions);
	});

	//*********************************************************************************************
[false, true].forEach(function (bWithLateQueryOptions) {
	var sTitle = "refreshReturnValueContext, with late query options = " + bWithLateQueryOptions;

	QUnit.test(sTitle, function (assert) {
		var oContext = Context.create(this.oModel, {}, "/SalesOrderList('42')"),
			oBinding = this.bindContext("bound.Operation(...)", oContext),
			oCache = {},
			bDependentsRefreshed = false,
			oDependentsPromise = new SyncPromise(function (resolve) {
				setTimeout(function () {
					bDependentsRefreshed = true;
					resolve();
				});
			}),
			mQueryOptions = {},
			oReturnValueContext = Context.create(this.oModel, oBinding, "/SalesOrderList('77')"),
			oRefreshPromise;

		oBinding.mLateQueryOptions = bWithLateQueryOptions ? {} : undefined;
		oBinding.oReturnValueContext = oReturnValueContext;
		this.mock(oBinding).expects("computeOperationQueryOptions").withExactArgs()
			.returns(bWithLateQueryOptions ? "~operationQueryOptions~" : mQueryOptions);
		this.mock(_Helper).expects("clone").exactly(bWithLateQueryOptions ? 1 : 0)
			.withExactArgs("~operationQueryOptions~").returns(mQueryOptions);
		this.mock(_Helper).expects("aggregateExpandSelect")
			.exactly(bWithLateQueryOptions ? 1 : 0)
			.withExactArgs(sinon.match.same(mQueryOptions),
				sinon.match.same(oBinding.mLateQueryOptions));
		this.mock(_Cache).expects("createSingle")
			.withExactArgs(sinon.match.same(this.oModel.oRequestor), "SalesOrderList('77')",
				sinon.match.same(mQueryOptions), true,
				sinon.match.same(this.oModel.bSharedRequests))
			.returns(oCache);
		this.mock(oBinding).expects("createReadGroupLock")
			.withExactArgs("group", true);
		this.mock(oReturnValueContext).expects("refreshDependentBindings")
			.withExactArgs("", "group", true, undefined)
			.returns(oDependentsPromise);

		// code under test
		oRefreshPromise = oBinding.refreshReturnValueContext(oReturnValueContext, "group");

		assert.strictEqual(oRefreshPromise.isPending(), true);
		assert.strictEqual(oBinding.mCacheQueryOptions, mQueryOptions);
		assert.strictEqual(oBinding.oCache, oCache);
		assert.strictEqual(oBinding.oCachePromise.getResult(), oCache);

		// code under test
		assert.strictEqual(
			oBinding.refreshReturnValueContext(oBinding.getBoundContext(), "group"),
			null);

		return oRefreshPromise.then(function () {
			assert.strictEqual(bDependentsRefreshed, true);
		});
	});
});

	//*********************************************************************************************
[false, true].forEach(function (bKeepCacheOnError) {
	[false, true].forEach(function (bCheckFails) {
		var sTitle = "refreshReturnValueContext: keep cache on error: " + bKeepCacheOnError
				+ ", check fails: " + bCheckFails;

	QUnit.test(sTitle, function (assert) {
		var oBinding = this.bindContext("bound.Operation(...)",
				Context.create(this.oModel, {}, "/SalesOrderList('42')")),
			oCheckError = new Error("checkUpdateInternal intentionally failed"),
			oError = new Error("This call intentionally failed"),
			oNewCache = {},
			oOldCache = {
				setActive : mustBeMocked
			},
			oReturnValueContext = Context.create(this.oModel, oBinding, "/SalesOrderList('77')"),
			that = this;

		oBinding.oCache = oOldCache;
		oBinding.oCachePromise = SyncPromise.resolve(oOldCache);
		oBinding.mCacheQueryOptions = "~mCacheQueryOptions~";
		oBinding.oReturnValueContext = oReturnValueContext;
		this.mock(oBinding).expects("computeOperationQueryOptions").withExactArgs()
			.returns("~mQueryOptions~");
		this.mock(_Helper).expects("aggregateExpandSelect").never();
		this.mock(_Cache).expects("createSingle")
			.withExactArgs(sinon.match.same(this.oModel.oRequestor), "SalesOrderList('77')",
				"~mQueryOptions~", true, sinon.match.same(this.oModel.bSharedRequests))
			.returns(oNewCache);
		this.mock(oBinding).expects("createReadGroupLock").withExactArgs("group", true);
		this.mock(oReturnValueContext).expects("refreshDependentBindings")
			.withExactArgs("", "group", true, bKeepCacheOnError).callsFake(function () {
				that.mock(oOldCache).expects("setActive").exactly(bKeepCacheOnError ? 1 : 0)
					.withExactArgs(true);
				that.mock(oReturnValueContext).expects("checkUpdateInternal")
					.exactly(bKeepCacheOnError ? 1 : 0).withExactArgs()
					.returns(bKeepCacheOnError && bCheckFails
						? SyncPromise.reject(oCheckError)
						: SyncPromise.resolve());
				return Promise.reject(oError);
			});

		// code under test
		return oBinding.refreshReturnValueContext(oReturnValueContext, "group", bKeepCacheOnError)
			.then(function () {
				assert.ok(false, "unexpected success");
			}, function (oError0) {
				assert.strictEqual(oError0,
					bKeepCacheOnError && bCheckFails ? oCheckError : oError);
				assert.strictEqual(oBinding.oCache,
					bKeepCacheOnError ? oOldCache : oNewCache);
				assert.strictEqual(oBinding.oCachePromise.getResult(),
					bKeepCacheOnError ? oOldCache : oNewCache);
				assert.strictEqual(oBinding.mCacheQueryOptions,
					bKeepCacheOnError ? "~mCacheQueryOptions~" : "~mQueryOptions~");
			});
	});
	});
});

	//*********************************************************************************************
[0, 1, 2].forEach(function (iOperation) {
	[false, true].forEach(function (bWithContext) {
		[false, true].forEach(function (bRecursionRejects) {
			var sTitle = "requestSideEffects, with context: " + bWithContext
					+ "; recursion rejects: " + bRecursionRejects
					+ "; operation setup #" + iOperation;

			QUnit.test(sTitle, function (assert) {
				// Note: w/o a context, the binding would be relative in real life
				var oBinding = this.bindContext("/Me/name.space.Operation(...)"),
					oCache = {
						requestSideEffects : function () {}
					},
					oCanceledError = new Error(),
					oContext = bWithContext
						? {getPath : function () {}}
						: undefined,
					oError = new Error(),
					sGroupId = "group",
					oGroupLock = {},
					oModelMock = this.mock(this.oModel),
					aPaths = [],
					oPromise = Promise.resolve({/*the updated data